package com.kcwl.carrier.application.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.kcwl.aid.interfaces.api.IOcrService;
import com.kcwl.aid.interfaces.dto.OcrLogDTO;
import com.kcwl.aid.interfaces.query.OcrLogQuery;
import com.kcwl.auxiliary.interfaces.api.IFreightAuxiliaryManageService;
import com.kcwl.auxiliary.interfaces.dto.FreightAuxiliaryManageDTO;
import com.kcwl.auxiliary.interfaces.query.FreightAuxiliaryManageQuery;
import com.kcwl.carrier.domain.condition.BizTagsRefCondition;
import com.kcwl.carrier.domain.entity.CancelApproveRemarkCommand;
import com.kcwl.carrier.domain.entity.*;
import com.kcwl.carrier.domain.service.*;
import com.kcwl.carrier.infrastructure.constant.LockConstants;
import com.kcwl.carrier.infrastructure.constant.VehicleConstant;
import com.kcwl.carrier.infrastructure.enums.*;
import com.kcwl.carrier.infrastructure.exceptions.CarrierUserException;
import com.kcwl.carrier.infrastructure.repository.po.VehicleTrailerPO;
import com.kcwl.carrier.infrastructure.utils.DateUtil;
import com.kcwl.carrier.infrastructure.utils.SysUtil;
import com.kcwl.carrier.interfaces.command.*;
import com.kcwl.carrier.interfaces.dto.*;
import com.kcwl.carrier.interfaces.enums.InviteStatusEnum;
import com.kcwl.carrier.interfaces.enums.VehicleInfoEnums;
import com.kcwl.carrier.interfaces.query.*;
import com.kcwl.ddd.application.constants.IdentityTypeEnum;
import com.kcwl.ddd.application.constants.YesNoEnum;
import com.kcwl.ddd.infrastructure.api.ResponseMessage;
import com.kcwl.ddd.interfaces.dto.ListResultDTO;
import com.kcwl.ddd.interfaces.dto.PageInfoDTO;
import com.kcwl.delivery.interfaces.api.IOrderService;
import com.kcwl.delivery.interfaces.command.DeliveryIdCommand;
import com.kcwl.delivery.interfaces.dto.OrderDetailDTO;
import com.kcwl.delivery.interfaces.query.OrderListQuery;
import com.kcwl.file.interfaces.api.IFileRemoteService;
import com.kcwl.file.interfaces.dto.FileUrlDTO;
import com.kcwl.file.interfaces.query.FileUrlQuery;
import com.kcwl.framework.lock.annotations.KcLock;
import com.kcwl.framework.utils.JsonUtil;
import com.kcwl.framework.utils.KcBeanConverter;
import com.kcwl.mdm.interfaces.api.IVehicleTypeService;
import com.kcwl.mdm.interfaces.dto.VehicleTypeDTO;
import com.kcwl.mdm.interfaces.query.VehicleTypeDetailQuery;
import com.kcwl.mdm.interfaces.query.VehicleTypeQuery;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.validation.constraints.NotNull;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static java.util.regex.Pattern.compile;

/**
 * @描述 车辆信息
 * @创建人 zhl
 * @创建时间 2022/11/1
 * @修改人和其它信息
 */
@Slf4j
@Service
public class VehicleApplicationService {

    @Autowired
    private VehicleInfoDomainService vehicleInfoDomainService;
    @Autowired
    private QualificationInfoDomainService qualificationInfoDomainService;
    @Autowired
    private TrailerApplicationService trailerApplicationService;
    @Autowired
    private CarrierInfoDomainService carrierInfoDomainService;
    @Autowired
    private VehicleTrailerDomainService vehicleTrailerDomainService;
    @Autowired
    private CarrierMappingDomainService carrierMappingDomainService;
    @Autowired
    private AuditRejectReasonDomainService auditRejectReasonDomainService;
    @Autowired
    private VehiclePlateCityRefDomainService vehiclePlateCityRefDomainService;
    @Autowired
    private CancelApproveRemarkDomainService cancelApproveRemarkDomainService;
    @Autowired
    private VehicleBlacklistDomainService vehicleBlacklistDomainService;
    @Autowired
    private BizTagsRefDomainService bizTagsRefDomainService;
    @Autowired
    private OperateLogApplicationService operateLogApplicationService;
    @Autowired
    private ReleaseDriverLogDomainService releaseDriverLogDomainService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IVehicleTypeService vehicleTypeService;
    @Autowired
    private IOcrService ocrService;
    @Autowired
    private IFileRemoteService fileRemoteService;
    @Autowired
    private IFreightAuxiliaryManageService freightAuxiliaryManageService;
    @Autowired
    private VehicleFastBindingInfoDomainService fastBindingInfoDomainService;

    @Autowired
    private CarrierUserApplicationService carrierUserApplicationService;

    @Autowired
    private ForeignDriverApplicationService foreignDriverApplicationService;
    private VehicleCommand vehicleCommand;

    @KcLock(key = "#vehicleCommand.plateNumber", prefix = LockConstants.VEHICLE_KEY)
    @Transactional(rollbackFor = Exception.class)
    public VehicleInfoDTO addVehicle(VehicleCommand vehicleCommand) {

        //车牌号长度、车牌颜色校验
        checkExtParms(vehicleCommand);

        VehicleInfo vehicleInfo = KcBeanConverter.toBean(vehicleCommand, VehicleInfo.class);
        // 获取司机id
        Long userId = vehicleCommand.getUserId();
        //获取平台码区分哪个平台认证车辆
        String platform = vehicleCommand.getPlatform();
        if (StringUtil.isNotEmpty(platform)) {
            vehicleInfo.setRegisterSource(CarrierInfoEnums.RegisterSourceEnum.getCode(platform));
        }

        //司机的身份类型 1司机，3车队长
        CarrierInfo carrier = carrierInfoDomainService.queryByUserId(userId);

        //校验司机准驾车型跟该车辆是否符合
        checkDrivingModel(vehicleCommand.getVehicleType(), carrier);

        // 校验车辆是否在黑名单里
        if (Objects.equals(isJoinBlackList(vehicleInfo.getPlateNumber()).getFlag(), YesNoEnum.YEA.getValue())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_ILLEGAL_FAIL);
        }

        //当前司机绑定车辆总数
        if (checkVehicleCount(userId, carrier)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_NUM_LIMIT);
        }

        //校验车辆是否已经被添加
        if (checkVehicleExist(vehicleInfo.getPlateNumber(), userId, null)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.REPEATED_APPLY);
        }

        // 组装车辆信息
        setVehicle(vehicleCommand, vehicleInfo);

        // 添加车辆信息
        SpringUtil.getApplicationContext().getBean(VehicleApplicationService.class)
            .addVehicleInfo(vehicleCommand, vehicleInfo, carrier);

        return KcBeanConverter.toBean(vehicleInfo, VehicleInfoDTO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addVehicleInfo(VehicleCommand vehicleCommand, VehicleInfo vehicleInfo, CarrierInfo carrier) {
        // 插入车辆信息
        Long id = vehicleInfoDomainService.addVehicleInfo(vehicleInfo);

        vehicleInfo.setId(id);
        vehicleInfo.setCarrierId(vehicleCommand.getCarrierId());
        //更新绑定该车的车辆类型vehicle_category
        updateVehicleCategory(vehicleInfo);

        //创建车主司机车辆默认关联关系
        addCarrierMapping(vehicleInfo, vehicleCommand.getUserId(), carrier.getIdentityType());

        ResponseMessage<VehicleTypeDTO> responseMessage =
            vehicleTypeService.queryVehicleTypeDetail(new VehicleTypeDetailQuery(vehicleInfo.getVehicleType()));
        VehicleTypeDTO vehicleTypeDTO = responseMessage.getResult();
        //需要添加挂车信息
        if (ObjectUtil.isNotEmpty(vehicleTypeDTO) && YesNoEnum.YEA.getValue() == vehicleTypeDTO.getTrailerFlag()
            .intValue()) {
            insertVehicleTrailer(vehicleCommand, vehicleInfo.getId());
        }

        // 添加审核日志
        operateLogApplicationService.registVehicleLog(id, vehicleCommand.getUserId());
    }

    /**
     * @描述 车牌号长度、车牌颜色校验
     * @参数 [vehicleCommand]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    private void checkExtParms(VehicleCommand vehicleCommand) {
        // 车牌颜色校验
        if (vehicleCommand.getPlateNumberColor() == VehicleInfoEnums.PlateNumberColorEnum.GREEN.getCode() || vehicleCommand.getPlateNumberColor() == VehicleInfoEnums.PlateNumberColorEnum.BLUE.getCode()) {
            if (vehicleCommand.getLoads() > VehicleConstant.VEHICLE_LOAD) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLEINFO_NOT_PATCH);
            }
        } else if (vehicleCommand.getPlateNumberColor() == VehicleInfoEnums.PlateNumberColorEnum.YELLOW.getCode() || vehicleCommand.getPlateNumberColor() == VehicleInfoEnums.PlateNumberColorEnum.YELLOW_GREEN.getCode()) {
            if (vehicleCommand.getLoads() <= VehicleConstant.VEHICLE_LOAD) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLEINFO_NOT_PATCH);
            }
        }

        // 车辆能源类型是新能源/电
        if (VehicleInfoEnums.VehicleCategoryEnum.NEW_ENERGY.getCode() == vehicleCommand.getVehicleCategory()) {
            if (vehicleCommand.getPlateNumber().length() != VehicleConstant.VEHICLE_PLATENUMBER_NEW) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLEINFO_NOT_PATCH);
            }
            if (vehicleCommand.getPlateNumberColor() != VehicleInfoEnums.PlateNumberColorEnum.GREEN.getCode() && vehicleCommand.getPlateNumberColor() != VehicleInfoEnums.PlateNumberColorEnum.YELLOW_GREEN.getCode()) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLEINFO_NOT_PATCH);
            }
        } else {
            if (vehicleCommand.getPlateNumber().length() != VehicleConstant.VEHICLE_PLATENUMBER) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLEINFO_NOT_PATCH);
            }
            if (vehicleCommand.getPlateNumberColor() != VehicleInfoEnums.PlateNumberColorEnum.YELLOW.getCode() && vehicleCommand.getPlateNumberColor() != VehicleInfoEnums.PlateNumberColorEnum.BLUE.getCode()) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLEINFO_NOT_PATCH);
            }
        }

        // 校验车辆道路运输证
        if (vehicleCommand.getLoads() > VehicleConstant.VEHICLE_LOAD) {
            if (StringUtils.isEmpty(vehicleCommand.getRoadTransCertiNumber()) || StringUtils.isEmpty(
                vehicleCommand.getRoadTransportPic())) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.ROADTRANSPORT_NOT_NULL);
            }
        }
    }

    /**
     * @描述 校验车辆时否被其他人绑定
     * @参数 [plateNumber, userId, vehicleId]
     * @返回值 boolean
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    private boolean checkVehicleExist(String plateNumber, Long userId, Long vehicleId) {
        VehicleInfo vehicleInfo = new VehicleInfo();
        vehicleInfo.setIsDel(BigInteger.ZERO.intValue());
        vehicleInfo.setCarrierId(userId);
        vehicleInfo.setPlateNumber(plateNumber);
        List<VehicleInfo> list = vehicleInfoDomainService.queryList(vehicleInfo);
        if (ObjectUtil.isNotEmpty(vehicleId)) {
            return !list.isEmpty() ? !list.get(0).getId().equals(vehicleId) : !list.isEmpty();
        } else {
            return !list.isEmpty();
        }
    }

    /**
     * @描述 校验审核通过的用户添加的车辆和准驾车型是否符合
     * @参数 [vehicleType, carrier]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    private Boolean checkDrivingModel(Long vehicleType, CarrierInfo carrier) {
        if (carrier.getIdentityType() == IdentityTypeEnum.CARRIER_DRIVER.getSubType()
            .intValue() && carrier.getIdentifyStatus() == VehicleInfoEnums.AuthenticationStatusEnum.VERIFIED.getCode()) {
            ResponseMessage<VehicleTypeDTO> responseMessage =
                vehicleTypeService.queryVehicleTypeDetail(new VehicleTypeDetailQuery(vehicleType));
            VehicleTypeDTO vehicleTypeDTO = responseMessage.getResult();
            if (!vehicleTypeDTO.getAllowedDrivingModels().contains(carrier.getAllowDrivingModel())) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_TYPE_NOT_PATCH);
            }
        }
        return Boolean.TRUE;
    }

    /**
     * @描述 校验司机绑定车辆是否超过最大限制
     * @参数 [userId, carrierInfo]
     * @返回值 boolean
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    private boolean checkVehicleCount(Long userId, CarrierInfo carrierInfo) {
        VehicleInfo countVehicleInfo = new VehicleInfo();
        countVehicleInfo.setIsDel(BigInteger.ZERO.intValue());
        countVehicleInfo.setCarrierId(userId);
        Integer count = vehicleInfoDomainService.selectCount(countVehicleInfo);

        // 司机下绑定车辆是否达到上限
        return count >= carrierInfo.getVehicleBingingLimit();
    }

    /**
     * @描述 校验车辆是否在黑名单里面
     * @参数 [plateNumber]
     * @返回值 java.lang.Integer
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    public FlagDTO isJoinBlackList(String plateNumber) {
        FlagDTO flagDTO = new FlagDTO();
        if (StringUtils.isEmpty(plateNumber)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.PLATENUMBER_NOT_NULL);
        }

        VehicleBlacklistCondition conditionVo = new VehicleBlacklistCondition();
        conditionVo.setIsDel(YesNoEnum.NAY.getValue());
        conditionVo.setPlateNumber(plateNumber);
        List<VehicleBlacklistInfo> vehicleBlacklistVos =
            vehicleBlacklistDomainService.queryVehicleBlacklistList(conditionVo);

        if (!CollectionUtils.isEmpty(vehicleBlacklistVos)) {
            flagDTO.setFlag(YesNoEnum.YEA.getValue());
        } else {
            flagDTO.setFlag(YesNoEnum.NAY.getValue());
        }

        return flagDTO;
    }

    /**
     * @描述 添加挂车
     * @参数 [vehicleCommand, vehicleId]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    void insertVehicleTrailer(VehicleCommand vehicleCommand, Long vehicleId) {
        if (StringUtil.isEmpty(vehicleCommand.getTrailerTransportationFrontPic()) || StringUtil.isEmpty(
            vehicleCommand.getTrailerPlateNumber()) || ObjectUtil.isEmpty(
            vehicleCommand.getTrailerPlateNumberColor())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.TRAILERINFO_NOT_NULL);
        }

        int trailerPlateNumberLength = vehicleCommand.getTrailerPlateNumber().length();
        if (trailerPlateNumberLength < VehicleConstant.VEHICLE_PLATENUMBER || trailerPlateNumberLength > VehicleConstant.VEHICLE_PLATENUMBER_NEW) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.PLATENUMBER_NOT_NULL);
        }

        VehicleTrailerInfo vehicleTrailer = new VehicleTrailerInfo();
        vehicleTrailer.setCarrierId(vehicleCommand.getUserId());
        vehicleTrailer.setPlateColor(vehicleCommand.getTrailerPlateNumberColor());
        vehicleTrailer.setPlateNumber(vehicleCommand.getTrailerPlateNumber());
        vehicleTrailer.setTransportationFrontPic(vehicleCommand.getTrailerTransportationFrontPic());
        trailerApplicationService.addTrailer(vehicleTrailer, vehicleId, 1);
    }

    /**
     * @描述 添加车主和车辆司机的关联关系
     * @参数 [vehicleInfo, userId, identityType]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    private void addCarrierMapping(VehicleInfo vehicleInfo, Long userId, Integer identityType) {
        //添加车主、车辆和司机的关联关系 carrier_mapping
        CarrierMappingInfo carrierMapping = new CarrierMappingInfo();
        carrierMapping.setCarrierId(userId);
        carrierMapping.setVehicleId(vehicleInfo.getId());
        carrierMapping.setCreateTime(new Date());
        carrierMapping.setIsDel(YesNoEnum.NAY.getValue());
        //设置默认添加司机授权抢单
        carrierMapping.setGrabOrderAuth(YesNoEnum.YEA.getValue());
        if (identityType == IdentityTypeEnum.CARRIER_DRIVER.getSubType().intValue()) {
            carrierMapping.setDriverId(userId);
        }

        //添加车主、车辆和司机的关联关系
        carrierMappingDomainService.addCarrierMapping(carrierMapping);
    }

    /**
     * @描述 更新绑定车辆类型
     * @参数 [vehicleInfo, userId]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    private void updateVehicleCategory(VehicleInfo vehicleInfo) {
        vehicleInfoDomainService.updateVehicleCategory(vehicleInfo);
    }

    /**
     * @描述 组装车辆信息
     * @参数 [vehicleCommand, vehicleInfo, userId]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    private void setVehicle(VehicleCommand vehicleCommand, VehicleInfo vehicleInfo) {
        vehicleInfo.setSource(VehicleInfoEnums.SourceEnum.NEW.getCode());
        vehicleInfo.setCarrierId(vehicleCommand.getCarrierId());
        vehicleInfo.setAuthenticationStatus(1);
        vehicleInfo.setIsDel(YesNoEnum.NAY.getValue());
        vehicleInfo.setSubmitTime(new Date());

        //校验司机是否被注销过
        checkUserTag(vehicleCommand.getUserId());

        //设置车牌前缀获取车辆所在省市
        setAreas(vehicleInfo);

        if (!SysUtil.isEmpty(vehicleCommand.getDrivingLicenseRegisterTime())) {
            vehicleInfo.setDrivingLicenseRegisterTime(
                DateUtil.getDate(vehicleCommand.getDrivingLicenseRegisterTime(), DateUtil.DEF_DATE_FORMAT));
        }
        if (!SysUtil.isEmpty(vehicleCommand.getDrivingLicenseStartTime())) {
            vehicleInfo.setDrivingLicenseStartTime(
                DateUtil.getDate(vehicleCommand.getDrivingLicenseStartTime(), DateUtil.DEF_DATE_FORMAT));
        }
        if (!SysUtil.isEmpty(vehicleCommand.getDrivingLicenseEndTime())) {
            vehicleInfo.setDrivingLicenseEndTime(
                DateUtil.getDate(vehicleCommand.getDrivingLicenseEndTime(), DateUtil.DATE_TIME));
        }
    }

    /**
     * @描述 校验司机是否被注销
     * @参数 [userId]
     * @返回值 java.lang.Object
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    public Boolean checkUserTag(Long userId) {
        // 查询司机详情
        CarrierInfo carrierInfo = carrierInfoDomainService.queryByCarrierId(userId);

        if (ObjectUtil.isNotEmpty(carrierInfo) && Objects.equals(carrierInfo.getCancer(), YesNoEnum.YEA.getValue())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.CARRIER_IS_NOT_EXISTS);
        }

        return Boolean.FALSE;
    }

    /**
     * @描述 根据车牌前缀获取车辆所在省市
     * @参数 [vehicleInfo]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2022/11/1
     * @修改人和其它信息
     */
    private void setAreas(VehicleInfo vehicleInfo) {
        VehiclePlateCityRef vehiclePlateCityRef =
            vehiclePlateCityRefDomainService.queryByPlateNo(vehicleInfo.getPlateNumber().substring(0, 2));
        if (ObjectUtil.isNotEmpty(vehiclePlateCityRef)) {
            vehicleInfo.setProvince(vehiclePlateCityRef.getProvince());
            vehicleInfo.setProvinceid(Integer.parseInt(vehiclePlateCityRef.getProvinceid()));
            vehicleInfo.setCity(vehiclePlateCityRef.getCity());
            vehicleInfo.setCityid(Integer.parseInt(vehiclePlateCityRef.getCityid()));
        }
    }

    /**
     * @描述 获取我的车辆列表
     * @参数 [vehicleCommand]
     * @返回值 com.kcwl.ddd.interfaces.dto.PageInfoDTO<com.kcwl.carrier.domain.entity.VehicleInfoVo>
     * @创建人 zhl
     * @创建时间 2022/11/3
     * @修改人和其它信息
     */
    public PageInfoDTO<VehicleInfoDTO> getVehiclePage(VehicleQuery query) {
        query.setCarrierId(query.getUserId());
        PageInfoDTO<VehicleInfoDTO> pageInfoDTO = vehicleInfoDomainService.getVehiclePage(query);
        List<VehicleInfoDTO> infoDTOS = pageInfoDTO.getList();

        // 查询挂车列表
        List<Long> trailerIds = infoDTOS.stream().map(VehicleInfoDTO::getTrailerId).collect(Collectors.toList());
        Map<Long, VehicleTrailerInfo> trailerInfoMap = new HashMap<>();
        if (trailerIds.size() > 0) {
            List<VehicleTrailerInfo> trailerInfos = vehicleTrailerDomainService.getByIds(trailerIds);
            trailerInfoMap =
                trailerInfos.stream().collect(Collectors.toMap(VehicleTrailerInfo::getId, Function.identity()));
        }
        if (infoDTOS.size() > 0) {
            // 查询车型列表
            List<Long> typeList = infoDTOS.stream().map(VehicleInfoDTO::getVehicleType).collect(Collectors.toList());
            Map<Long, VehicleTypeDTO> vehicleTypeMap = getVehicleType(typeList);

            Map<Long, VehicleTrailerInfo> finalTrailerInfoMap = trailerInfoMap;
            infoDTOS.forEach(v -> {
                // 暂时写死收纳状态
                v.setTakeStatus(10);

                if (ObjectUtil.isNotEmpty(v.getTrailerId())) {
                    VehicleTrailerInfo trailerInfo = finalTrailerInfoMap.get(v.getTrailerId());
                    v.setTrailerPlateNumber(trailerInfo.getPlateNumber());
                    v.setTrailerPlateNumberColor(trailerInfo.getPlateColor());
                    v.setTrailerTransportationFrontPic(trailerInfo.getTransportationFrontPic());
                    v.setTrailerAuthenticationStatus(trailerInfo.getAuthenticationStatus());
                    v.setTrailerOcrDrivingLicense(trailerInfo.getTrailerOcrDrivingLicense());
                }

                if (ObjectUtil.isNotEmpty(v.getPlateNumberColor())) {
                    v.setFormatPlateNumberColor(VehicleInfoEnums.PlateNumberColorEnum.getDesc(v.getPlateNumberColor()));
                }
                if (ObjectUtil.isNotEmpty(v.getTrailerPlateNumberColor())) {
                    v.setFormatTrailerPlateColor(
                        VehicleInfoEnums.PlateNumberColorEnum.getDesc(v.getTrailerPlateNumberColor()));
                }
                if (ObjectUtil.isNotEmpty(v.getEmissionsStandard())) {
                    v.setEmissionsStandardDesc(
                        VehicleInfoEnums.EmissionsStandardEnum.getDesc(v.getEmissionsStandard()));
                }
                if (ObjectUtil.isNotEmpty(v.getVehicleCategory())) {
                    v.setFormatVehicleCategory(VehicleInfoEnums.VehicleCategoryEnum.getDesc(v.getVehicleCategory()));
                }
                if (ObjectUtil.isNotEmpty(
                    v.getAuthenticationStatus()) && v.getAuthenticationStatus() != AuditAuthenticationStatusEnum.FAILURE.getCode()) {
                    v.setRejectReason("");
                }
                if (ObjectUtil.isNotEmpty(v.getDriverId())) {
                    v.setBindStatus(YesNoEnum.YEA.getValue());
                } else {
                    v.setBindStatus(YesNoEnum.NAY.getValue());
                }

                if (ObjectUtil.isNotEmpty(v.getVehicleType())) {
                    VehicleTypeDTO vehicleTypeDTO = vehicleTypeMap.get(v.getVehicleType());
                    v.setVehicleTypeName(vehicleTypeDTO.getVehicleTypeName());
                    v.setIsTrailer(vehicleTypeDTO.getTrailerFlag().byteValue());
                    v.setAllowedDrivingModels(vehicleTypeDTO.getAllowedDrivingModels());
                }

                if (ObjectUtil.equals(query.getIdentityType(), IdentityTypeEnum.CARRIER_DRIVER.getSubType())) {
                    v.setDriverName(null);
                    v.setDriverMobile(null);
                    if (ObjectUtil.equals(v.getIdentityType(),
                        IdentityTypeEnum.CARRIER_SFLTOP.getSubType()) || ObjectUtil.equals(v.getIdentityType(),
                        IdentityTypeEnum.CARRIER_TCOM_MANAGER.getSubType())) {
                        v.setCarrierVehicleRef(YesNoEnum.YEA.getValue());
                    } else {
                        v.setCarrierVehicleRef(YesNoEnum.NAY.getValue());
                    }
                } else {
                    v.setCarrierVehicleRef(YesNoEnum.NAY.getValue());
                }

                // 处理驳回原因
                setRejectReasons(v);

                // 车辆被准驾车型
                if (!com.kcwl.framework.utils.StringUtil.isEmpty(
                    v.getAllowedDrivingModels()) && v.getAllowedDrivingModels().contains("@")) {
                    String[] models = v.getAllowedDrivingModels().split("@");
                    if (ObjectUtil.isNotEmpty(
                        v.getPlateNumberColor()) && v.getPlateNumberColor() > 0 && v.getPlateNumberColor() <= models.length) {
                        v.setAllowedDrivingModels(models[v.getPlateNumberColor() - 1]);
                    } else {
                        v.setAllowedDrivingModels(models[0]);
                    }
                }
            });
        }
        pageInfoDTO.setList(infoDTOS);
        return pageInfoDTO;
    }

    /**
     * @描述 获取车型
     * @参数 [typeList]
     * @返回值 java.util.Map<java.lang.Long, com.kcwl.mdm.interfaces.dto.VehicleTypeDTO>
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    private Map<Long, VehicleTypeDTO> getVehicleType(List<Long> typeList) {
        ResponseMessage<ListResultDTO<VehicleTypeDTO>> responseMessage =
            vehicleTypeService.queryVehicleType(new VehicleTypeQuery(typeList));
        List<VehicleTypeDTO> dtoList = responseMessage.getResult().getList();
        Map<Long, VehicleTypeDTO> vehicleTypeMap =
            dtoList.stream().collect(Collectors.toMap(VehicleTypeDTO::getVehicleType, Function.identity()));
        return vehicleTypeMap;
    }

    /**
     * 处理车辆驳回原因
     *
     * @param vehicleInfoDTO
     */
    private void setRejectReasons(VehicleInfoDTO vehicleInfoDTO) {
        if (!com.kcwl.framework.utils.StringUtil.isEmpty(vehicleInfoDTO.getRejectReason())) {
            String rejectReason = vehicleInfoDTO.getRejectReason();
            // 查找规则公式中大括号以内的字符
            Pattern p = compile("\\[.*?\\]");
            Matcher m = p.matcher(rejectReason);
            // 遍历找到的所有大括号
            StringBuilder reasonBuilder = new StringBuilder();

            while (m.find()) {
                // 去掉括号
                String param = m.group().replace("[", "").replace("]", "");
                if (StringUtil.isNotEmpty(param)) {
                    reasonBuilder.append(param).append(",");
                }
            }

            String reason = reasonBuilder.toString();
            if (!com.kcwl.framework.utils.StringUtil.isEmpty(reason)) {
                List<Long> ids = Arrays.asList(reason.split(",")).parallelStream().map(a -> Long.parseLong(a.trim()))
                    .collect(Collectors.toList());
                // 调用驳回原因接口
                List<AuditRejectReasonInfo> auditRejectReasons = auditRejectReasonDomainService.selectIds(ids);
                List<String> rejectReasons = new ArrayList<>();
                auditRejectReasons.forEach(a -> {
                    rejectReasons.add(a.getGroupName() + a.getReason());
                });
                vehicleInfoDTO.setRejectReason(vehicleInfoDTO.getAuthenticationRemark());
                vehicleInfoDTO.setRejectReasonList(rejectReasons);
            }
        }
    }

    /**
     * 车主给车辆分配/修改司机
     *
     * @param command
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean changeDriver(ChangeDriverCommand command) {
        Long driverId = command.getDriverId();
        Long vehicleId = command.getVehicleId();

        // 司机车辆准驾车型符不符合
        checkAllowDrivingModel(vehicleId, driverId);

        Long carrierId = command.getUserId();
        if (ObjectUtil.isEmpty(carrierId)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.CARRIER_NOT_LOGIN);
        }

        // 根据车主和车辆查询（车辆关系）
        CarrierMappingInfo vehicleCon = new CarrierMappingInfo();
        vehicleCon.setCarrierId(carrierId);
        vehicleCon.setVehicleId(vehicleId);
        List<CarrierMappingInfo> vehicleMappingList = carrierMappingDomainService.getMappingList(vehicleCon);

        // 查询车辆信息
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(vehicleId);
        if (vehicleMappingList.isEmpty() || ObjectUtil.isEmpty(vehicleInfo) || !vehicleInfo.getCarrierId()
            .equals(carrierId)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_NOT_YOU);
        }

        CarrierMappingInfo carrierMapping = vehicleMappingList.get(0);
        if (ObjectUtil.isNotEmpty(carrierMapping.getDriverId())) {//车辆已绑定司机
            Long nowDriverId = carrierMapping.getDriverId();
            if (nowDriverId.equals(driverId)) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.DRIVER_BINDED_VIHICLE);
            }
        }

        // 绑定车辆和司机
        bindVehicleDriver(carrierMapping, driverId);
        return true;
    }

    /**
     * @描述 审核通过的司机添加车辆校验准驾车型跟该车辆是否符合
     * @参数
     * @返回值
     * @创建人 zhl
     * @创建时间 2022/11/3
     * @修改人和其它信息
     */
    private void checkAllowDrivingModel(Long vehicleId, Long driverId) {
        // 查询车辆信息
        VehicleInfo vehicle = vehicleInfoDomainService.queryById(vehicleId);
        // 查询司机信息
        CarrierInfo carrierInfo = carrierInfoDomainService.queryByCarrierId(driverId);
        checkDrivingModel(vehicle.getVehicleType(), carrierInfo);
    }

    /**
     * @描述 司机和车辆绑定
     * @参数 [carrierMapping, driverId]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    private void bindVehicleDriver(CarrierMappingInfo carrierMapping, Long driverId) {
        // 更新关系
        carrierMapping.setDriverId(driverId);
        carrierMappingDomainService.updateCarrierMapping(carrierMapping);
    }

    /**
     * @描述 编辑车辆
     * @参数 [vehicleCommand]
     * @返回值 java.lang.Long
     * @创建人 zhl
     * @创建时间 2022/11/15
     * @修改人和其它信息
     */
    @Transactional(rollbackFor = Exception.class)
    public Long updateVehicle(VehicleCommand vehicleCommand) {
        // 车牌号长度、车牌颜色校验
        checkExtParms(vehicleCommand);
        VehicleCopyCommand command = KcBeanConverter.toBean(vehicleCommand, VehicleCopyCommand.class);
        VehicleInfo vehicleInfo = KcBeanConverter.toBean(command, VehicleInfo.class);
        vehicleInfo.setId(vehicleCommand.getVehicleId());
        if (!SysUtil.isEmpty(vehicleCommand.getDrivingLicenseRegisterTime())) {
            vehicleInfo.setDrivingLicenseRegisterTime(
                DateUtil.getDate(vehicleCommand.getDrivingLicenseRegisterTime(), DateUtil.DEF_DATE_FORMAT));
        }
        if (!SysUtil.isEmpty(vehicleCommand.getDrivingLicenseStartTime())) {
            vehicleInfo.setDrivingLicenseStartTime(
                DateUtil.getDate(vehicleCommand.getDrivingLicenseStartTime(), DateUtil.DEF_DATE_FORMAT));
        }
        if (!SysUtil.isEmpty(vehicleCommand.getDrivingLicenseEndTime())) {
            vehicleInfo.setDrivingLicenseEndTime(
                DateUtil.getDate(vehicleCommand.getDrivingLicenseEndTime(), DateUtil.DATE_TIME));
        }
        if (!SysUtil.isEmpty(vehicleCommand.getAuthenticationTime())) {
            vehicleInfo.setAuthenticationTime(
                DateUtil.getDate(vehicleCommand.getAuthenticationTime(), DateUtil.MINUTE_FORMAT));
        }
        if (!SysUtil.isEmpty(vehicleCommand.getDelTime())) {
            vehicleInfo.setDelTime(DateUtil.getDate(vehicleCommand.getDelTime(), DateUtil.MINUTE_FORMAT));
        }
        if (!SysUtil.isEmpty(vehicleCommand.getSubmitTime())) {
            vehicleInfo.setSubmitTime(DateUtil.getDate(vehicleCommand.getSubmitTime(), DateUtil.MINUTE_FORMAT));
        }
        if (!SysUtil.isEmpty(vehicleCommand.getEtcUpdateTime())) {
            vehicleInfo.setEtcUpdateTime(DateUtil.getDate(vehicleCommand.getEtcUpdateTime(), DateUtil.MINUTE_FORMAT));
        }
        if (!SysUtil.isEmpty(vehicleCommand.getPeriodStartDate())) {
            vehicleInfo.setPeriodStartDate(
                DateUtil.getDate(vehicleCommand.getPeriodStartDate(), DateUtil.DEF_DATE_FORMAT));
        }
        if (!SysUtil.isEmpty(vehicleCommand.getPeriodStartDate())) {
            vehicleInfo.setPeriodEndDate(DateUtil.getDate(vehicleCommand.getPeriodEndDate(), DateUtil.DEF_DATE_FORMAT));
        }

        // 审核通过的司机添加车辆校验准驾车型跟该车辆符不符合
        if (ObjectUtil.isNotEmpty(vehicleCommand.getVehicleType())) {
            checkDrivingModel(vehicleCommand.getVehicleType(),
                carrierInfoDomainService.queryByUserId(vehicleCommand.getCarrierId()));
        }

        // 修改车牌号不为空时校验是否重复了
        if (!StringUtils.isEmpty(vehicleInfo.getPlateNumber())) {
            if (checkVehicleExist(vehicleInfo.getPlateNumber(), vehicleCommand.getCarrierId(), vehicleInfo.getId())) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_REPEATED_ADD);
            }
        }

        // 需要更新挂车信息
        if (ObjectUtil.isNotEmpty(vehicleCommand.getVehicleType())) {
            updateVehicleTrailer(vehicleCommand);
        }

        // 获取车辆详情
        VehicleIdQuery idQuery = new VehicleIdQuery();
        idQuery.setVehicleId(vehicleCommand.getVehicleId());
        idQuery.setUserId(vehicleCommand.getUserId());
        VehicleInfoDTO vehicleInfoDTO = getVehicleInfo(idQuery);
        // 校验审核状态
        if (ObjectUtil.equals(vehicleInfoDTO.getAuthenticationStatus(),
            VehicleInfoEnums.AuthenticationStatusEnum.VERIFIED)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.AUDITED);
        }
        if (ObjectUtil.equals(vehicleInfoDTO.getAuthenticationStatus(),
            VehicleInfoEnums.AuthenticationStatusEnum.UNVERIFIED)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.REPEATED_APPLY);
        }

        // 更新车辆信息
        vehicleInfoDomainService.updateVehicle(vehicleInfo);

        // 更新车辆标签
        if (!ObjectUtil.equals(vehicleCommand.getTagId(), vehicleInfoDTO.getTagId())) {
            bizTagsRefDomainService.saveOrUpdateBizTagsRef(vehicleInfo.getId(), AuditIdentityEnum.VEHICLE.getCode(),
                vehicleCommand.getTagId());
        }
        // 增加审核日志
        insertOperateLog(vehicleCommand, vehicleInfoDTO);

        return vehicleInfo.getId();
    }

    private void insertOperateLog(VehicleCommand vehicleCommand, VehicleInfoDTO vehicleInfo) {
        if (!ObjectUtil.equals(vehicleCommand.getPlateNumber(),
            ObjectUtil.isNotEmpty(vehicleInfo.getPlateNumber()) ? vehicleInfo.getPlateNumber() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "车牌修改",
                vehicleInfo.getPlateNumber());
        }
        if (!ObjectUtil.equals(vehicleCommand.getVehicleType(), vehicleInfo.getVehicleType())) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "车辆类型修改",
                ObjectUtil.isNotEmpty(vehicleInfo.getVehicleType()) ? vehicleInfo.getVehicleType().toString() : null);
        }
        if (!ObjectUtil.equals(vehicleCommand.getVehicleCategory(),
            ObjectUtil.isNotEmpty(vehicleInfo.getVehicleCategory()) ? vehicleInfo.getVehicleCategory() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "能源类型修改",
                ObjectUtil.isNotEmpty(vehicleInfo.getVehicleCategory()) ? vehicleInfo.getVehicleCategory().toString()
                    : null);
        }
        if (!ObjectUtil.equals(vehicleCommand.getPlateNumberColor(), vehicleInfo.getPlateNumberColor())) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "车牌颜色修改",
                ObjectUtil.isNotEmpty(vehicleInfo.getPlateNumberColor()) ? vehicleInfo.getPlateNumberColor().toString()
                    : null);
        }
        if (!ObjectUtil.equals(vehicleCommand.getLoads(), vehicleInfo.getLoads())) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "净重修改",
                ObjectUtil.isNotEmpty(vehicleInfo.getLoads()) ? vehicleInfo.getLoads().toString() : null);
        }
        if (!ObjectUtil.equals(vehicleCommand.getEmissionsStandard(),
            ObjectUtil.isNotEmpty(vehicleInfo.getEmissionsStandard()) ? vehicleInfo.getEmissionsStandard() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "车辆排放标准修改",
                ObjectUtil.isNotEmpty(vehicleInfo.getEmissionsStandard()) ? vehicleInfo.getEmissionsStandard()
                    .toString() : null);
        }
        if (!ObjectUtil.equals(vehicleCommand.getSize(),
            ObjectUtil.isNotEmpty(vehicleInfo.getSize()) ? vehicleInfo.getSize() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "车辆尺寸修改",
                vehicleInfo.getSize());
        }
        if (!ObjectUtil.equals(vehicleCommand.getRoadTransCertiNumber(),
            ObjectUtil.isNotEmpty(vehicleInfo.getRoadTransCertiNumber()) ? vehicleInfo.getRoadTransCertiNumber()
                : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "道路运输证号修改",
                vehicleInfo.getRoadTransCertiNumber());
        }
        String periodStartDate = DateUtil.formatDateTime(vehicleInfo.getPeriodStartDate());
        if (!ObjectUtil.equals(vehicleCommand.getPeriodStartDate(),
            ObjectUtil.isNotEmpty(periodStartDate) ? periodStartDate : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(),
                "道路运输证发证日期修改", periodStartDate);
        }
        if (!ObjectUtil.equals(vehicleCommand.getRoadTransportPic(),
            ObjectUtil.isNotEmpty(vehicleInfo.getRoadTransportPic()) ? vehicleInfo.getRoadTransportPic() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "道路运输证修改",
                vehicleInfo.getRoadTransportPic());
        }
        if (!ObjectUtil.equals(vehicleCommand.getOwner(),
            ObjectUtil.isNotEmpty(vehicleInfo.getOwner()) ? vehicleInfo.getOwner() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "车辆所有人修改",
                vehicleInfo.getOwner());
        }
        if (!ObjectUtil.equals(vehicleCommand.getUsage(),
            ObjectUtil.isNotEmpty(vehicleInfo.getUsage()) ? vehicleInfo.getUsage() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "使用性质修改",
                vehicleInfo.getUsage());
        }
        if (!ObjectUtil.equals(vehicleCommand.getAddress(),
            ObjectUtil.isNotEmpty(vehicleInfo.getAddress()) ? vehicleInfo.getAddress() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "住址修改",
                vehicleInfo.getAddress());
        }
        if (!ObjectUtil.equals(vehicleCommand.getBrandModel(),
            ObjectUtil.isNotEmpty(vehicleInfo.getBrandModel()) ? vehicleInfo.getBrandModel() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "品牌型号修改",
                vehicleInfo.getBrandModel());
        }
        if (!ObjectUtil.equals(vehicleCommand.getEngineNumber(),
            ObjectUtil.isNotEmpty(vehicleInfo.getEngineNumber()) ? vehicleInfo.getEngineNumber() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "发动机号码修改",
                vehicleInfo.getEngineNumber());
        }
        if (!ObjectUtil.equals(vehicleCommand.getVin(),
            ObjectUtil.isNotEmpty(vehicleInfo.getVin()) ? vehicleInfo.getVin() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "车辆识别代号修改",
                vehicleInfo.getVin());
        }
        String drivingLicenseRegisterTime = DateUtil.formatDateTime(vehicleInfo.getDrivingLicenseRegisterTime());
        if (!ObjectUtil.equals(vehicleCommand.getDrivingLicenseRegisterTime(),
            ObjectUtil.isNotEmpty(drivingLicenseRegisterTime) ? drivingLicenseRegisterTime : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "行驶证注册日期修改",
                drivingLicenseRegisterTime);
        }
        String drivingLicenseEndTime = DateUtil.formatDateTime(vehicleInfo.getDrivingLicenseEndTime());
        if (!ObjectUtil.equals(vehicleCommand.getDrivingLicenseEndTime(),
            ObjectUtil.isNotEmpty(drivingLicenseEndTime) ? drivingLicenseEndTime : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "有效截止月份修改",
                drivingLicenseEndTime);
        }
        if (!ObjectUtil.equals(vehicleCommand.getDrivingLicenseNumber(),
            ObjectUtil.isNotEmpty(vehicleInfo.getDrivingLicenseNumber()) ? vehicleInfo.getDrivingLicenseNumber()
                : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "行驶证档案编号修改",
                vehicleInfo.getDrivingLicenseNumber());
        }
        String drivingLicenseStartTime = DateUtil.formatDateTime(vehicleInfo.getDrivingLicenseStartTime());
        if (!ObjectUtil.equals(vehicleCommand.getDrivingLicenseStartTime(),
            ObjectUtil.isNotEmpty(drivingLicenseStartTime) ? drivingLicenseStartTime : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "行驶证发证日期修改",
                drivingLicenseStartTime);
        }
        if (!ObjectUtil.equals(vehicleCommand.getDrivingLicensePic(),
            ObjectUtil.isNotEmpty(vehicleInfo.getDrivingLicensePic()) ? vehicleInfo.getDrivingLicensePic() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "行驶证图片修改",
                vehicleInfo.getDrivingLicensePic());
        }
        if (!ObjectUtil.equals(vehicleCommand.getHasRelation(), vehicleInfo.getHasRelation())) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "车辆-车主关系修改",
                ObjectUtil.isNotEmpty(vehicleInfo.getHasRelation()) ? vehicleInfo.getHasRelation().toString() : null);
        }
        if (!ObjectUtil.equals(vehicleCommand.getRelatedPoofPic(),
            ObjectUtil.isNotEmpty(vehicleInfo.getRelatedPoofPic()) ? vehicleInfo.getRelatedPoofPic() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "车辆关联证明修改",
                vehicleInfo.getRelatedPoofPic());
        }
        if (!ObjectUtil.equals(vehicleCommand.getTagId(), vehicleInfo.getTagId())) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "平台车辆标签修改",
                ObjectUtil.isNotEmpty(vehicleInfo.getTagId()) ? vehicleInfo.getTagId().toString() : null);
        }
        if (!ObjectUtil.equals(vehicleCommand.getAuthenticationRemark(),
            ObjectUtil.isNotEmpty(vehicleInfo.getAuthenticationRemark()) ? vehicleInfo.getAuthenticationRemark()
                : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "客服备注修改",
                vehicleInfo.getAuthenticationRemark());
        }
        if (!ObjectUtil.equals(vehicleCommand.getLabel(),
            ObjectUtil.isNotEmpty(vehicleInfo.getLabel()) ? vehicleInfo.getLabel() : "")) {
            operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(), "标签修改",
                vehicleInfo.getLabel());
        }
        if (ObjectUtil.isNotEmpty(vehicleCommand.getVehicleType())) {
            if (!ObjectUtil.equals(vehicleCommand.getTrailerPlateNumber(),
                ObjectUtil.isNotEmpty(vehicleInfo.getTrailerPlateNumber()) ? vehicleInfo.getTrailerPlateNumber()
                    : "")) {
                operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(),
                    "挂车车牌号修改", vehicleInfo.getTrailerPlateNumber());
            }
            if (!ObjectUtil.equals(vehicleCommand.getTrailerPlateNumberColor(),
                ObjectUtil.isNotEmpty(vehicleInfo.getTrailerPlateNumberColor())
                    ? vehicleInfo.getTrailerPlateNumberColor() : "")) {
                operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(),
                    "挂车车牌颜色修改", ObjectUtil.isNotEmpty(vehicleInfo.getTrailerPlateNumberColor())
                        ? vehicleInfo.getTrailerPlateNumberColor().toString() : null);
            }
            if (!ObjectUtil.equals(vehicleCommand.getTrailerTransportationFrontPic(),
                ObjectUtil.isNotEmpty(vehicleInfo.getTrailerTransportationFrontPic())
                    ? vehicleInfo.getTrailerTransportationFrontPic() : "")) {
                operateLogApplicationService.updateVehicleLog(vehicleInfo.getId(), vehicleCommand.getUserId(),
                    "挂车行驶证图片修改", vehicleInfo.getTrailerTransportationFrontPic());
            }
        }
    }

    /**
     * 挂车车辆 驳回 修改
     *
     * @param vehicleCommand 修改的参数
     */
    public void updateVehicleTrailer(VehicleCommand vehicleCommand) {
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(vehicleCommand.getVehicleId());
        VehicleTrailerInfo vehicleTrailer = new VehicleTrailerInfo();
        vehicleTrailer.setPlateColor(vehicleCommand.getTrailerPlateNumberColor());
        vehicleTrailer.setPlateNumber(vehicleCommand.getTrailerPlateNumber());
        vehicleTrailer.setTransportationFrontPic(vehicleCommand.getTrailerTransportationFrontPic());
        vehicleTrailer.setAuthenticationStatus(VehicleInfoEnums.AuthenticationStatusEnum.UNVERIFIED.getCode());
        vehicleTrailer.setSubmitTime(new Date());
        vehicleTrailer.setId(vehicleInfo.getTrailerId());
        vehicleTrailer.setCarrierId(vehicleCommand.getCarrierId());

        // 查询修改之后的车辆类型
        ResponseMessage<VehicleTypeDTO> responseMessage =
            vehicleTypeService.queryVehicleTypeDetail(new VehicleTypeDetailQuery(vehicleCommand.getVehicleType()));
        VehicleTypeDTO vehicleTypeDTO = responseMessage.getResult();

        // 新修改的车辆类型变成重型半挂牵引车
        if (YesNoEnum.YEA.getValue() == vehicleTypeDTO.getTrailerFlag().intValue()) {
            trailerApplicationService.update(vehicleTrailer, vehicleCommand.getVehicleId());
        } else {
            // 修改车辆表中挂车id为null
            vehicleInfoDomainService.updateVehicleTrail(vehicleCommand.getVehicleId());
            vehicleTrailer.setIsDel(YesNoEnum.YEA.getValue());
            vehicleTrailerDomainService.updateById(vehicleTrailer);
        }
    }

    /**
     * 重新认证
     *
     * @param command
     * @return: com.kcwl.carrier.domain.entity.VehicleInfo
     * @author: healen
     * @date: 2022/11/8 14:58
     */
    @Transactional(rollbackFor = Exception.class)
    public VehicleInfo rebindAddVehicle(VehicleRebindCommand command) {
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(command.getHistoryVehicleId());
        // 用户id
        Long userId = command.getUserId();

        if (ObjectUtil.isEmpty(userId)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.CARRIER_NOT_LOGIN);
        }

        // 校验司机是否被注销
        this.checkUserTag(userId);

        // 校验车辆是否在黑名单中
        if (Objects.equals(isJoinBlackList(vehicleInfo.getPlateNumber()).getFlag(), YesNoEnum.YEA.getValue())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_ILLEGAL_FAIL);
        }

        // 校验车辆是否已添加
        if (checkVehicleExist(vehicleInfo.getPlateNumber(), userId, null)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.REPEATED_APPLY);
        }

        // 校验当前司机绑定车辆总数
        if (checkVehicleCount(userId, carrierInfoDomainService.queryByUserId(userId))) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_NUM_LIMIT);
        }

        // 校验车辆是否已认证
        if (VehicleInfoEnums.AuthenticationStatusEnum.VERIFIED.getCode() != vehicleInfo.getAuthenticationStatus()) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_AUTH_NOT_APPROVE);
        }

        // 校验车牌号长度、车牌颜色
        VehicleCommand vehicleCommand = KcBeanConverter.toBean(vehicleInfo, VehicleCommand.class);
        this.checkExtParms(vehicleCommand);

        // 校验车辆道路运输证日期
        if (ObjectUtil.isEmpty(vehicleInfo.getPeriodEndDate()) || new Date().after(vehicleInfo.getPeriodEndDate())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.PERIODENDDATE_NOT_EXIST_OR_OVER);
        }

        // 校验登录人身份类型
        if (Objects.equals(command.getIdentityType(), IdentityTypeEnum.CARRIER_SFLTOP.getSubType()) || Objects.equals(
            command.getIdentityType(), IdentityTypeEnum.CARRIER_TDSPR.getSubType())) {
            if (ObjectUtil.isEmpty(vehicleInfo.getRelatedPoofPic())) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.RELATEDPOOFPIC_NOT_EXIST);
            }
        }

        // 校验是否是挂车,是否存在挂车信息
        VehicleIdQuery query = new VehicleIdQuery();
        query.setVehicleId(vehicleInfo.getId());
        if (!this.isExistTrailerInfo(query)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.TRAILERINFO_NOT_EXIST);
        }

        vehicleInfo.setCarrierId(userId);
        vehicleInfo.setIsDel(YesNoEnum.NAY.getValue());
        vehicleInfo.setDelTime(null);
        vehicleInfo.setSource(YesNoEnum.NAY.getValue());

        // 根据是否是挂车，添加车辆，更新车辆
        if (ObjectUtil.isNotEmpty(vehicleInfo.getTrailerId())) {
            // 查询挂车信息
            VehicleTrailerInfo trailerInfo = vehicleTrailerDomainService.getById(vehicleInfo.getTrailerId());
            VehicleTrailerPO trailerPO = KcBeanConverter.toBean(trailerInfo, VehicleTrailerPO.class);

            // 保存挂车信息
            vehicleTrailerDomainService.save(trailerPO);
            vehicleInfo.setTrailerId(trailerPO.getId());
        }

        // 重新绑定则新增，驳回则修改
        if (ObjectUtil.isNotEmpty(command.getVehicleId())) {
            // 修改车辆信息
            vehicleInfo.setId(command.getVehicleId());
            vehicleInfoDomainService.updateVehicle(vehicleInfo);
        } else {
            // 插入车辆信息
            vehicleInfo.setId(vehicleInfoDomainService.insert(vehicleInfo));

            // 创建车主司机车辆默认关联关系
            this.addCarrierMapping(vehicleInfo, userId, command.getIdentityType());
        }

        return vehicleInfo;
    }

    /**
     * @description: 取消车辆认证
     * @author: healen
     * @date: 2022/11/8 14:48
     * @param: conditionVo
     * @return: com.kcwl.carrier.domain.entity.CancelApproveRemarkInfo
     */
    @Transactional(rollbackFor = Exception.class)
    public CancelApproveRemarkInfo cancelApprove(CancelApproveRemarkCommand conditionVo) {
        return cancelApproveRemarkDomainService.addRemark(conditionVo);
    }

    /**
     * @描述 删除车辆
     * @参数 [command]
     * @返回值 java.lang.Boolean
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteVehicle(VehicleInfoDeleteCommand command) {
        // 校验车辆信息
        VehicleInfo vehicleInfo = validVehicleInfo(command);

        // 3.删除车辆
        vehicleInfo.setIsDel(YesNoEnum.YEA.getValue());
        vehicleInfo.setDelTime(new Date());
        vehicleInfoDomainService.updateVehicle(vehicleInfo);

        //  4.删除carrier_mapping
        CarrierMappingInfo carrierMapping = new CarrierMappingInfo();
        carrierMapping.setVehicleId(vehicleInfo.getId());
        carrierMappingDomainService.deleteByVehicleId(carrierMapping);

        // 5.删除挂车
        VehicleInfo v = vehicleInfoDomainService.queryById(command.getVehicleId());
        if (ObjectUtil.isNotEmpty(v.getTrailerId())) {
            VehicleTrailerInfo info = new VehicleTrailerInfo();
            info.setIsDel(YesNoEnum.YEA.getValue());
            info.setId(v.getTrailerId());
            vehicleTrailerDomainService.updateTrailer(info);
        }

        return Boolean.TRUE;
    }

    /**
     * @描述 校验车辆信息
     * @参数 [command]
     * @返回值 com.kcwl.carrier.domain.entity.VehicleInfo
     * @创建人 zhl
     * @创建时间 2023/1/3
     * @修改人和其它信息
     */
    private VehicleInfo validVehicleInfo(VehicleInfoDeleteCommand command) {

        // 查询车辆信息
        Long vehicleId = command.getVehicleId();
        VehicleInfo vehicleInfo = new VehicleInfo();
        vehicleInfo.setCarrierId(command.getUserId());
        vehicleInfo.setId(vehicleId);
        VehicleInfo info = vehicleInfoDomainService.queryById(vehicleId);
        if (ObjectUtil.isEmpty(info)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_NOT_EXIST);
        }

        // 校验车辆是否和司机绑定
        if (!Objects.equals(info.getCarrierId(), command.getUserId())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_DRIVER_NOT_BIND);
        }

        // 1.是否设置车辆代收
        ResponseMessage<FreightAuxiliaryManageDTO> response = freightAuxiliaryManageService.queryOne(
            FreightAuxiliaryManageQuery.builder().targetId(vehicleId).carrierId(vehicleInfo.getCarrierId()).build());
        if (response.isSuccess() && ObjectUtil.isNotEmpty(response.getResult())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_SET_COLLECT);
        }

        // 2.车辆是否有在途订单
        OrderListQuery query = new OrderListQuery();
        // 设置在途状态
        query.setStatusList(ListUtil.toList(106, 110));
        query.setVehicleIds(ListUtil.toList(vehicleId));
        ResponseMessage<List<OrderDetailDTO>> responseMessage = orderService.queryOrderListByParam(query);
        if (responseMessage.isSuccess()) {
            List<OrderDetailDTO> orderDetailDTOS = responseMessage.getResult();
            if (!orderDetailDTOS.isEmpty() && orderDetailDTOS.size() > BigInteger.ZERO.intValue()) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_BIND_VALIDORDER);
            }
        }

        return vehicleInfo;
    }

    /**
     * @描述 解除车辆绑定
     * @参数 [command]
     * @返回值 java.lang.Object
     * @创建人 zhl
     * @创建时间 2022/11/15
     * @修改人和其它信息
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean unbindVehicle(VehicleInfoDeleteCommand command) {
        // 校验车辆信息
        VehicleInfo vehicleInfo = validVehicleInfo(command);

        // 查询当前车辆目前有关订单以及承运司机信息
        OrderListQuery query = new OrderListQuery();
        query.setVehicleIds(ListUtil.toList(vehicleInfo.getId()));
        ResponseMessage<List<OrderDetailDTO>> responseMessage = orderService.queryOrderListByParam(query);
        if (responseMessage.isSuccess()) {
            List<OrderDetailDTO> orderDetailDTOS = responseMessage.getResult();

            // 查询司机信息
            CarrierInfo carrierInfo = carrierInfoDomainService.queryByCarrierId(command.getUserId());

            // 3.插入司机和车辆解除关系的日志
            for (OrderDetailDTO OrderDetailDTO : orderDetailDTOS) {
                ReleaseDriverLogInfo releaseDriverLog = new ReleaseDriverLogInfo();
                releaseDriverLog.setOrderId(OrderDetailDTO.getId());
                releaseDriverLog.setOrderStatus(OrderDetailDTO.getOrderStatus());
                releaseDriverLog.setDriverId(command.getUserId());
                releaseDriverLog.setVehicleId(vehicleInfo.getId());
                releaseDriverLog.setDriverName(carrierInfo.getName());
                releaseDriverLog.setDriverMobile(carrierInfo.getMobile());
                releaseDriverLog.setCreateTime(new Date());
                releaseDriverLogDomainService.save(releaseDriverLog);
            }
        }

        // 3.删除车辆
        vehicleInfo.setIsDel(YesNoEnum.YEA.getValue());
        vehicleInfo.setDelTime(new Date());
        vehicleInfo.setCarrierId(null);
        vehicleInfoDomainService.updateVehicle(vehicleInfo);

        //  4.删除carrier_mapping
        CarrierMappingInfo carrierMapping = new CarrierMappingInfo();
        carrierMapping.setVehicleId(vehicleInfo.getId());
        carrierMappingDomainService.deleteByVehicleId(carrierMapping);

        // 5.修改订单表中该车辆下不在途订单的driver_id变为空
        DeliveryIdCommand deliveryIdCommand = new DeliveryIdCommand();
        deliveryIdCommand.setId(vehicleInfo.getId());
        orderService.unbindOrderForVehicle(deliveryIdCommand);

        return Boolean.TRUE;
    }

    /**
     * @描述 车辆详情
     * @参数 [query]
     * @返回值 com.kcwl.carrier.interfaces.dto.VehicleInfoDTO
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public VehicleInfoDTO getVehicleInfo(VehicleIdQuery query) {
        // 查询车辆信息
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(query.getVehicleId());

        // 组装dto信息
        VehicleInfoDTO vehicleInfoDTO = KcBeanConverter.toBean(vehicleInfo, VehicleInfoDTO.class);
        vehicleInfoDTO.setVehicleLoads(vehicleInfo.getLoads());
        if (ObjectUtil.isNotEmpty(vehicleInfo.getDrivingLicenseRegisterTime())) {
            vehicleInfoDTO.setDrivingLicenseRegisterTimeStr(
                DateUtil.formatDate(vehicleInfo.getDrivingLicenseRegisterTime(), DateUtil.DEF_DATE_FORMAT));
        }
        if (ObjectUtil.isNotEmpty(vehicleInfo.getDrivingLicenseStartTime())) {
            vehicleInfoDTO.setDrivingLicenseStartTimeStr(
                DateUtil.formatDate(vehicleInfo.getDrivingLicenseStartTime(), DateUtil.DEF_DATE_FORMAT));
        }
        if (ObjectUtil.isNotEmpty(vehicleInfo.getDrivingLicenseEndTime())) {
            vehicleInfoDTO.setDrivingLicenseEndTimeStr(
                DateUtil.formatDate(vehicleInfo.getDrivingLicenseEndTime(), DateUtil.DATE_TIME));
        }
        if (!com.kcwl.framework.utils.StringUtil.isEmpty(vehicleInfoDTO.getHistoryRemark())) {
            Map<String, Object> map = JsonUtil.fromJson(vehicleInfoDTO.getHistoryRemark(), Map.class);
            String remark = (String)map.get("remark");
            String updateTime = (String)map.get("updateTime");
            String[] remarks = remark.split("@");
            String[] updateTimes = updateTime.split("@");
            List<Map<String, Object>> lists = new ArrayList<>();
            if (remarks.length > 1) {
                for (int i = 0; i < remarks.length; i++) {
                    Map<String, Object> resMap = new HashMap<>();
                    resMap.put("remark", remarks[i]);
                    resMap.put("updateTime", updateTimes[i]);
                    lists.add(resMap);
                }
            } else {
                lists.add(map);
            }
            vehicleInfoDTO.setHistoryRemarks(lists);
        }

        // 扩展车辆类型
        if (ObjectUtil.isNotEmpty(vehicleInfo.getVehicleType())) {
            ResponseMessage<VehicleTypeDTO> responseMessage =
                vehicleTypeService.queryVehicleTypeDetail(new VehicleTypeDetailQuery(vehicleInfo.getVehicleType()));
            VehicleTypeDTO vehicleType = responseMessage.getResult();
            vehicleInfoDTO.setVehicleTypeName(vehicleType.getVehicleTypeName());
            vehicleInfoDTO.setIsTrailer(vehicleType.getTrailerFlag().byteValue());
            vehicleInfoDTO.setGrabOrderCapacity(vehicleType.getGrabOrderCapacity());
            vehicleInfoDTO.setGrabOrderLoad(vehicleType.getGrabOrderLoad());
        }

        // 挂车信息
        if (ObjectUtil.isNotEmpty(vehicleInfo.getTrailerId())) {
            VehicleTrailerInfo vehicleTrailer = vehicleTrailerDomainService.getById(vehicleInfo.getTrailerId());
            vehicleInfoDTO.setTrailerTransportationFrontPic(vehicleTrailer.getTransportationFrontPic());
            vehicleInfoDTO.setTrailerPlateNumber(vehicleTrailer.getPlateNumber());
            vehicleInfoDTO.setTrailerPlateNumberColor(vehicleTrailer.getPlateColor());
        }

        // 字典描述信息
        if (ObjectUtil.isNotEmpty(vehicleInfoDTO.getPlateNumberColor())) {
            vehicleInfoDTO.setFormatPlateNumberColor(
                VehicleInfoEnums.PlateNumberColorEnum.getDesc(vehicleInfoDTO.getPlateNumberColor()));
        }
        if (ObjectUtil.isNotEmpty(vehicleInfoDTO.getTrailerPlateNumberColor())) {
            vehicleInfoDTO.setFormatTrailerPlateColor(
                VehicleInfoEnums.PlateNumberColorEnum.getDesc(vehicleInfoDTO.getTrailerPlateNumberColor()));
        }
        if (ObjectUtil.isNotEmpty(vehicleInfoDTO.getEmissionsStandard())) {
            vehicleInfoDTO.setEmissionsStandardDesc(
                VehicleInfoEnums.EmissionsStandardEnum.getDesc(vehicleInfoDTO.getEmissionsStandard()));
        }
        if (ObjectUtil.isNotEmpty(vehicleInfoDTO.getVehicleCategory())) {
            vehicleInfoDTO.setFormatVehicleCategory(
                VehicleInfoEnums.VehicleCategoryEnum.getDesc(vehicleInfoDTO.getVehicleCategory()));
        }
        setRejectReasons(vehicleInfoDTO);

        // 司机和车辆绑定关系
        CarrierMappingInfo cm =
            carrierMappingDomainService.getDriverByVehicleId(query.getVehicleId(), vehicleInfo.getCarrierId());
        if (ObjectUtil.isNotEmpty(cm)) {
            // 司机信息
            if (ObjectUtil.isNotEmpty(cm.getDriverId())) {
                CarrierInfo carrierInfo = carrierInfoDomainService.queryByCarrierId(cm.getDriverId());
                vehicleInfoDTO.setDriverMobile(carrierInfo.getMobile());
                vehicleInfoDTO.setDriverName(carrierInfo.getName());
                vehicleInfoDTO.setDriverId(cm.getDriverId());
            }
        }

        // 车主信息
        CarrierInfo carrierInfo = carrierInfoDomainService.queryByCarrierId(vehicleInfoDTO.getCarrierId());
        vehicleInfoDTO.setCarrierName(carrierInfo.getName());
        vehicleInfoDTO.setCarrierMobile(carrierInfo.getMobile());
        vehicleInfoDTO.setIdentityType(carrierInfo.getIdentityType().toString());
        vehicleInfoDTO.setCarrierAuthenticationStatus(carrierInfo.getAuthenticationStatus());

        // 查询车辆标签
        BizTagsRefCondition condition = new BizTagsRefCondition();
        condition.setBizType(BizTypeEnum.BIZ_VEHICLE.getCode());
        condition.setBizId(vehicleInfo.getId());
        List<BizTagsRefInfo> bizTagsRefInfos = bizTagsRefDomainService.queryBizTagsRefList(condition);
        if (bizTagsRefInfos.size() > 0) {
            vehicleInfoDTO.setTagId(bizTagsRefInfos.get(0).getTagId());
        }

        // 查询ocr日志
        OcrLogQuery ocrLogQuery = new OcrLogQuery();
        ocrLogQuery.setKeys(ListUtil.toList(vehicleInfoDTO.getDrivingLicensePic()));
        ResponseMessage<Map<String, OcrLogDTO>> responseMessage = ocrService.queryOcrLog(ocrLogQuery);
        Map<String, OcrLogDTO> logDTOMap = null;
        if (responseMessage.isSuccess()) {
            logDTOMap = responseMessage.getResult();
        }
        Map<String, OcrLogDTO> finalLogDTOMap = logDTOMap;
        String scrapEndDate = getScrapEndDate(finalLogDTOMap, vehicleInfoDTO.getDrivingLicensePic());
        vehicleInfoDTO.setScrapEndDate(scrapEndDate);
        return vehicleInfoDTO;
    }

    /**
     * @描述 获取历史车辆
     * @参数 [query]
     * @返回值 com.kcwl.carrier.interfaces.dto.VehicleInfoDTO
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public VehicleInfoDTO getHistoryVehicle(PlateNumberQuery query) {
        VehicleInfo vehicleInfo = new VehicleInfo();
        vehicleInfo.setIsDel(YesNoEnum.YEA.getValue());
        vehicleInfo.setCarrierId(query.getUserId());
        vehicleInfo.setPlateNumber(query.getPlateNumber());
        vehicleInfo.setAuthenticationStatus(VehicleInfoEnums.AuthenticationStatusEnum.VERIFIED.getCode());
        VehicleInfoVo historyVehicle = vehicleInfoDomainService.getHistoryVehicle(vehicleInfo);
        if (ObjectUtil.isEmpty(historyVehicle)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.DATA_NOT_EXIST);
        }

        // 该车辆道路运输证结束日期是否过期
        if (ObjectUtil.isNotEmpty(historyVehicle.getPeriodEndDate())) {
            long time = historyVehicle.getPeriodEndDate().getTime();
            if (time <= System.currentTimeMillis()) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.TRANSPORT_EXPIRED);
            }
        }
        if (ObjectUtil.isNotEmpty(historyVehicle.getDrivingLicenseRegisterTime())) {
            historyVehicle.setDrivingLicenseRegisterTimeStr(
                DateUtil.formatDate(historyVehicle.getDrivingLicenseRegisterTime(), DateUtil.DEF_DATE_FORMAT));
        }
        if (ObjectUtil.isNotEmpty(historyVehicle.getDrivingLicenseStartTime())) {
            historyVehicle.setDrivingLicenseStartTimeStr(
                DateUtil.formatDate(historyVehicle.getDrivingLicenseStartTime(), DateUtil.DEF_DATE_FORMAT));
        }
        if (ObjectUtil.isNotEmpty(historyVehicle.getDrivingLicenseEndTime())) {
            historyVehicle.setDrivingLicenseEndTimeStr(
                DateUtil.formatDate(historyVehicle.getDrivingLicenseEndTime(), DateUtil.DATE_TIME));
        }
        if (ObjectUtil.isNotEmpty(historyVehicle.getVehicleCategory())) {
            historyVehicle.setFormatVehicleCategory(
                VehicleInfoEnums.VehicleCategoryEnum.getDesc(historyVehicle.getVehicleCategory()));
        }
        if (ObjectUtil.isNotEmpty(historyVehicle.getPlateNumberColor())) {
            historyVehicle.setFormatPlateNumberColor(
                VehicleInfoEnums.PlateNumberColorEnum.getDesc(historyVehicle.getPlateNumberColor()));
        }
        if (ObjectUtil.isNotEmpty(historyVehicle.getEmissionsStandard())) {
            historyVehicle.setEmissionsStandardDesc(
                VehicleInfoEnums.EmissionsStandardEnum.getDesc(historyVehicle.getEmissionsStandard()));
        }
        if (org.apache.commons.lang.StringUtils.isNotBlank(historyVehicle.getDrivingLicensePic())) {
            historyVehicle.setDrivingLicensePicUrl(historyVehicle.getDrivingLicensePic());
        }
        if (org.apache.commons.lang.StringUtils.isNotBlank(historyVehicle.getRoadTransportPic())) {
            historyVehicle.setRoadTransportPicUrl(historyVehicle.getRoadTransportPic());
        }

        // 查询挂车信息
        VehicleTrailerInfo trailerDetail = vehicleTrailerDomainService.getById(historyVehicle.getTrailerId());
        if (ObjectUtil.isNotEmpty(trailerDetail)) {
            historyVehicle.setTrailerPlateNumber(trailerDetail.getPlateNumber());
            historyVehicle.setTrailerPlateNumberColor(trailerDetail.getPlateColor());
            historyVehicle.setTrailerTransportationFrontPic(trailerDetail.getTransportationFrontPic());
            if (ObjectUtil.isNotEmpty(trailerDetail.getPlateColor())) {
                historyVehicle.setFormatTrailerPlateColor(
                    VehicleInfoEnums.PlateNumberColorEnum.getDesc(trailerDetail.getPlateColor()));
            }
        }

        // 查询车型信息
        ResponseMessage<VehicleTypeDTO> responseMessage =
            vehicleTypeService.queryVehicleTypeDetail(new VehicleTypeDetailQuery(historyVehicle.getVehicleType()));
        VehicleTypeDTO vehicleTypeDTO = responseMessage.getResult();
        historyVehicle.setVehicleTypeName(vehicleTypeDTO.getVehicleTypeName());
        historyVehicle.setTrailerFlag(vehicleTypeDTO.getTrailerFlag());
        historyVehicle.setIsTrailer(vehicleTypeDTO.getTrailerFlag().byteValue());

        return KcBeanConverter.toBean(historyVehicle, VehicleInfoDTO.class);
    }

    /**
     * @描述 校验司机已添加车辆是否达上限
     * @参数 [userId]
     * @返回值 java.util.Map
     * @创建人 zhl
     * @创建时间 2022/12/23
     * @修改人和其它信息
     */
    public FlagDTO checkVehicleBingingLimit(Long userId) {
        FlagDTO limitFlagDTO = new FlagDTO();
        CarrierInfo carrier = carrierInfoDomainService.queryByCarrierId(userId);
        if (checkVehicleCount(userId, carrier)) {
            limitFlagDTO.setFlag(YesNoEnum.YEA.getValue());
        } else {
            limitFlagDTO.setFlag(YesNoEnum.NAY.getValue());
        }
        return limitFlagDTO;
    }

    /**
     * @描述 更新车辆维修状态
     * @参数 [command]
     * @返回值 java.lang.Long
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public Long updateVehicleMaintenanceStatus(VehicleEditCommand command) {
        VehicleInfo vehicleInfo = new VehicleInfo();
        vehicleInfo.setId(command.getVehicleId());
        vehicleInfo.setIsMaintaining(command.getIsMaintaining());
        vehicleInfoDomainService.updateVehicle(vehicleInfo);
        return vehicleInfo.getId();
    }

    /**
     * @描述 根据条件获取车辆数
     * @参数 [query]
     * @返回值 java.lang.Integer
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public Integer getVehicleCount(VehicleQuery query) {
        return vehicleInfoDomainService.getVehicleCount(query);
    }

    /**
     * 获取车辆上传证件照
     *
     * @param list
     * @return
     */
    private Map<String, String> getPicMap(List<VehicleInfoListDTO> list) {
        // 行驶证执照
        Set<String> drivingLicensePics =
            list.stream().map(VehicleInfoListDTO::getDrivingLicensePic).filter(Objects::nonNull)
                .collect(Collectors.toSet());
        // 道路运输证照
        Set<String> roadTransportPics =
            list.stream().map(VehicleInfoListDTO::getRoadTransportPic).filter(Objects::nonNull)
                .collect(Collectors.toSet());
        // 车辆关联证明照
        Set<String> relatedPoofPics =
            list.stream().map(VehicleInfoListDTO::getRelatedPoofPic).filter(x -> x != null && !x.contains(","))
                .collect(Collectors.toSet());
        // 挂车行驶证
        Set<String> trailerPics =
            list.stream().map(VehicleInfoListDTO::getTrailerTransportationFrontPic).filter(Objects::nonNull)
                .collect(Collectors.toSet());
        for (VehicleInfoListDTO vehicleInfoVo : list) {
            if (org.apache.commons.lang.StringUtils.isBlank(
                vehicleInfoVo.getRelatedPoofPic()) || !vehicleInfoVo.getRelatedPoofPic().contains(",")) {
                continue;
            }
            relatedPoofPics.addAll(
                Arrays.asList(org.apache.commons.lang.StringUtils.split(vehicleInfoVo.getRelatedPoofPic(), ",")));
        }

        drivingLicensePics.addAll(roadTransportPics);
        drivingLicensePics.addAll(relatedPoofPics);
        drivingLicensePics.addAll(trailerPics);
        Map<String, String> pairUrl = new HashMap<>();
        FileUrlQuery fileUrlQuery = new FileUrlQuery();
        fileUrlQuery.setKeys(ListUtil.toList(drivingLicensePics));
        ResponseMessage<List<FileUrlDTO>> urlByKeys = fileRemoteService.getUrlByKeys(fileUrlQuery);
        urlByKeys.getResult().forEach(fileUrlVo -> {
            pairUrl.put(fileUrlVo.getKey(), fileUrlVo.getUrl());
        });

        return pairUrl;
    }

    /**
     * @描述 车辆关联证明处理
     * @参数 [mapPic, relatedPoofPic]
     * @返回值 java.lang.String
     * @创建人 zhl
     * @创建时间 2023/1/11
     * @修改人和其它信息
     */
    private String relatedPoofPicHandler(Map<String, String> mapPic, String relatedPoofPic) {
        List<String> list = new ArrayList<>();
        if (StringUtil.isNotBlank(relatedPoofPic)) {
            if (relatedPoofPic.contains(",")) {
                String[] relatedPoofPicAttr = relatedPoofPic.split(",");
                for (int i = 0; i < relatedPoofPicAttr.length; i++) {
                    list.add(mapPic.get(relatedPoofPicAttr[i]));
                }
            } else {
                list.add(mapPic.get(relatedPoofPic));
            }
        }
        return Joiner.on(",").join(list);
    }

    /**
     * @描述 查询车辆列表（审核列表）
     * @参数 [query]
     * @返回值 com.kcwl.ddd.interfaces.dto.PageInfoDTO<com.kcwl.carrier.interfaces.dto.VehicleInfoListDTO>
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public PageInfoDTO<VehicleInfoListDTO> queryVehiclePage(VehicleQuery query) {
        // 调整请求参数
        getParams(query);

        // 查询车辆列表
        PageInfoDTO<VehicleInfoListDTO> pageInfoDTO = vehicleInfoDomainService.queryVehiclePage(query);
        List<VehicleInfoListDTO> infoDTOList = pageInfoDTO.getList();
        if (infoDTOList.size() > 0) {

            // 查询ocr日志
            List<String> ocrLogList =
                infoDTOList.stream().map(VehicleInfoListDTO::getDrivingLicensePic).collect(Collectors.toList());
            OcrLogQuery ocrLogQuery = new OcrLogQuery();
            ocrLogQuery.setKeys(ocrLogList);
            ResponseMessage<Map<String, OcrLogDTO>> responseMessage = ocrService.queryOcrLog(ocrLogQuery);
            Map<String, OcrLogDTO> logDTOMap = null;
            if (responseMessage.isSuccess()) {
                logDTOMap = responseMessage.getResult();
            }
            Map<String, OcrLogDTO> finalLogDTOMap = logDTOMap;

            // 查询车型
            List<Long> typeList =
                infoDTOList.stream().map(VehicleInfoListDTO::getVehicleType).collect(Collectors.toList());
            Map<Long, VehicleTypeDTO> vehicleTypeMap = getVehicleType(typeList);
            // 查询图片地址全路径
            Map<String, String> picMap = getPicMap(infoDTOList);
            infoDTOList.forEach(v -> {
                if (ObjectUtil.isNotEmpty(v.getPlateNumberColor())) {
                    v.setFormatPlateNumberColor(VehicleInfoEnums.PlateNumberColorEnum.getDesc(v.getPlateNumberColor()));
                }
                if (ObjectUtil.isNotEmpty(v.getTrailerPlateColor())) {
                    v.setFormatTrailerPlateColor(
                        VehicleInfoEnums.PlateNumberColorEnum.getDesc(v.getTrailerPlateColor()));
                }
                if (ObjectUtil.isNotEmpty(v.getEmissionsStandard())) {
                    v.setEmissionsStandardDesc(
                        VehicleInfoEnums.EmissionsStandardEnum.getDesc(v.getEmissionsStandard()));
                }
                if (ObjectUtil.isNotEmpty(v.getVehicleCategory())) {
                    v.setFormatVehicleCategory(VehicleInfoEnums.VehicleCategoryEnum.getDesc(v.getVehicleCategory()));
                }
                if (ObjectUtil.isNotEmpty(
                    v.getAuthenticationStatus()) && v.getAuthenticationStatus() != AuditAuthenticationStatusEnum.FAILURE.getCode()) {
                    v.setRejectReason("");
                }
                if (ObjectUtil.isNotEmpty(v.getVehicleType())) {
                    VehicleTypeDTO vehicleTypeDTO = vehicleTypeMap.get(v.getVehicleType());
                    if (ObjectUtil.isNotEmpty(vehicleTypeDTO)) {
                        v.setTypeName(vehicleTypeDTO.getVehicleTypeName());
                    }
                }
                if (ObjectUtil.isNotEmpty(v.getPeriodStartDate())) {
                    v.setPeriodStartDate(DateUtil.getDefDateFormatDate(v.getPeriodStartDate()));
                }
                if (ObjectUtil.isNotEmpty(v.getPeriodEndDate())) {
                    v.setPeriodEndDate(DateUtil.getDefDateFormatDate(v.getPeriodEndDate()));
                }

                // 设置图片路径
                if (!picMap.isEmpty()) {
                    v.setDrivingLicensePicAbs(picMap.get(v.getDrivingLicensePic()));
                    v.setRoadTransportPicAbs(picMap.get(v.getRoadTransportPic()));
                    v.setRelatedPoofPicAbs(relatedPoofPicHandler(picMap, v.getRelatedPoofPic()));
                    v.setTrailerTransportationFrontPicAbs(picMap.get(v.getTrailerTransportationFrontPic()));
                }
                // 设置强制报废日期
                String scrapEndDate = getScrapEndDate(finalLogDTOMap, v.getDrivingLicensePic());
                v.setScrapDate(scrapEndDate);

                if (!StringUtil.isEmpty(v.getHistoryRemark())) {
                    Map<String, Object> map = JsonUtil.fromJson(v.getHistoryRemark(), Map.class);
                    String remark = (String)map.get("remark");
                    String updateTime = (String)map.get("updateTime");
                    String[] remarks = remark.split("@");
                    String[] updateTimes = updateTime.split("@");
                    List<Map<String, Object>> lists = new ArrayList<>();
                    if (remarks.length > 1) {
                        for (int i = 0; i < remarks.length; i++) {
                            Map<String, Object> resMap = new HashMap<>();
                            resMap.put("remark", remarks[i]);
                            resMap.put("updateTime", updateTimes[i]);
                            lists.add(resMap);
                        }
                    } else {
                        lists.add(map);
                    }
                    v.setHistoryRemarks(lists);
                }
            });

            // 快速绑定车辆，高亮字段
            fillAuditVehicleHighLightFields(infoDTOList);
        }

        pageInfoDTO.setList(infoDTOList);
        return pageInfoDTO;
    }

    private void getParams(VehicleQuery query) {
        String mobileList = query.getMobileList();
        String plateNumberList = query.getPlateNumberList();
        if (!StringUtils.isEmpty(mobileList)) {
            if (mobileList.contains(",")) {
                query.setMobiles(ListUtil.toList(mobileList.split(",")));
            } else {
                query.setMobiles(ListUtil.toList(mobileList));
            }
        }
        if (!StringUtils.isEmpty(plateNumberList)) {
            if (plateNumberList.contains(",")) {
                query.setPlateNumbers(ListUtil.toList(plateNumberList.split(",")));
            } else {
                query.setPlateNumbers(ListUtil.toList(plateNumberList));
            }
        }
    }

    /**
     * 填充车辆审核数据，高亮字段
     */
    public void fillAuditVehicleHighLightFields(List<VehicleInfoListDTO> dtoList) {
        List<Long> vehicleIdList = dtoList.stream().map(VehicleInfoListDTO::getId).collect(Collectors.toList());
        if (CollUtil.isEmpty(vehicleIdList)) {
            return;
        }

        // 需要更新车辆关联证明的车辆
        Set<Long> needUpdateRelatedPoofModifyIds =
            new HashSet<>(fastBindingInfoDomainService.selectFastBindingVehicleIdByIds(vehicleIdList));

        dtoList.forEach(vehicleInfoListDTO -> {
            if (needUpdateRelatedPoofModifyIds.contains(vehicleInfoListDTO.getId())) {
                if (vehicleInfoListDTO.getHighLightFieldList() == null) {
                    vehicleInfoListDTO.setHighLightFieldList(new ArrayList<>());
                }

                // 车辆关联证明高亮
                vehicleInfoListDTO.getHighLightFieldList().add("relatedPoofPic");
            }
        });

    }

    /**
     * @描述 获取强制报废日期
     * @参数 [finalLogDTOMap, key]
     * @返回值 java.lang.String
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    private String getScrapEndDate(Map<String, OcrLogDTO> finalLogDTOMap, String key) {
        if (ObjectUtil.isNotEmpty(key)) {
            if (finalLogDTOMap != null) {
                OcrLogDTO ocrLogDTO = finalLogDTOMap.get(key);
                if (ObjectUtil.isNotEmpty(ocrLogDTO)) {
                    String analysisMsg = ocrLogDTO.getAnalysisMsg();
                    if (StringUtil.isNotEmpty(analysisMsg)) {
                        JsonObject jsonObject = JsonUtil.parseJson(analysisMsg);
                        if (ObjectUtil.isNotEmpty(jsonObject)) {
                            JsonObject licenseInfo = jsonObject.getAsJsonObject("licenseInfo");
                            if (ObjectUtil.isNotEmpty(licenseInfo)) {
                                JsonObject vehicle_back = licenseInfo.getAsJsonObject("vehicle_back");
                                if (ObjectUtil.isNotEmpty(vehicle_back)) {
                                    String scrapDate = vehicle_back.get("remark").getAsString();
                                    return scrapDate;
                                }
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * @描述 获取司机绑定车辆数
     * @参数 [query]
     * @返回值 java.util.Map<java.lang.Long, java.lang.Long>
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public Map<Long, Long> getCarrierBindVehicleCount(IdListQuery query) {
        List<VehicleInfoListVo> authCarNumList = vehicleInfoDomainService.findAuthCarNum(query.getIdList());
        return authCarNumList.stream()
            .collect(Collectors.toMap(VehicleInfoListVo::getCarrierId, VehicleInfoListVo::getCarNum, (k1, k2) -> k2));
    }

    /**
     * @描述 获取车辆挂靠清单
     * @参数 [query]
     * @返回值 java.util.List<com.kcwl.carrier.interfaces.dto.BindListDTO>
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public List<BindListDTO> getBindList(IdQuery query) {
        List<VehicleInfo> vehicleInfos = vehicleInfoDomainService.queryByIds(ListUtil.toList(query.getId()));
        List<Long> vehicleIds = vehicleInfos.stream().map(VehicleInfo::getId).collect(Collectors.toList());
        List<Long> carrierIds = vehicleInfos.stream().map(VehicleInfo::getCarrierId).collect(Collectors.toList());

        // 查询mapping关系
        List<CarrierMappingInfo> mappingInfos = carrierMappingDomainService.getByVehicleIds(vehicleIds);
        Map<Long, Date> mappingMap = mappingInfos.stream()
            .collect(Collectors.toMap(CarrierMappingInfo::getVehicleId, CarrierMappingInfo::getCreateTime));

        // 查询车主信息
        List<CarrierInfo> carrierInfos = carrierInfoDomainService.getByIds(carrierIds);
        Map<Long, String> mobileMap =
            carrierInfos.stream().collect(Collectors.toMap(CarrierInfo::getId, CarrierInfo::getMobile));
        ArrayList<BindListDTO> bindListDTOS = new ArrayList<>();
        vehicleInfos.forEach(vehicleInfo -> {
            BindListDTO bindListDTO = new BindListDTO();
            if (VehicleInfoEnums.AuthenticationStatusEnum.VERIFIED.getCode() == vehicleInfo.getAuthenticationStatus()) {
                bindListDTO.setValid(YesNoEnum.YEA.getValue());
            } else {
                bindListDTO.setValid(YesNoEnum.NAY.getValue());
            }
            bindListDTO.setBindTime(mappingMap.get(vehicleInfo.getId()));
            bindListDTO.setMobile(mobileMap.get(vehicleInfo.getId()));
            bindListDTOS.add(bindListDTO);
        });
        return bindListDTOS;
    }

    /**
     * @描述 获取车辆标签列表
     * @参数 [query]
     * @返回值 java.util.Map<java.lang.Long, java.lang.Long>
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public Map<Long, Long> getTagList(IdListQuery query) {
        BizTagsRefCondition condition = new BizTagsRefCondition();
        condition.setBizIds(query.getIdList());
        condition.setBizType(AuditIdentityEnum.VEHICLE.getCode());
        List<BizTagsRefInfo> bizTagsRefVos = bizTagsRefDomainService.queryBizTagsRefList(condition);
        Map<Long, Long> resultMap = new HashMap<>();
        if (bizTagsRefVos.size() > BigInteger.ZERO.intValue()) {
            resultMap = bizTagsRefVos.stream()
                .collect(Collectors.toMap(BizTagsRefInfo::getBizId, BizTagsRefInfo::getTagId, (k1, k2) -> k2));
        }
        return resultMap;
    }

    /**
     * @描述 更新道路运输许可证信息
     * @参数
     * @返回值
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public Boolean updateVehicleCertificates(VehicleQualificationCommand command) {
        // 查询车辆信息
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(command.getVehicleId());
        if (ObjectUtil.isEmpty(vehicleInfo)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.DATA_NOT_EXIST);
        }
        if (vehicleInfo.getAuthenticationStatus() != VehicleInfoEnums.AuthenticationStatusEnum.VERIFIED.getCode()) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.AUTH_IS_NOT_EXISTS);
        }

        // 查询相关证件信息
        QualificationInfo qualificationInfo = KcBeanConverter.toBean(command, QualificationInfo.class);
        qualificationInfo.setBizId(command.getUserId());
        qualificationInfo.setBizType(BizTypeEnum.BIZ_CARRIER.getCode());
        QualificationInfo byBizId = qualificationInfoDomainService.getByBizId(qualificationInfo);

        // 为空修改
        if (ObjectUtil.isNotEmpty(byBizId)) {
            byBizId.setRoadTransLicensePic(command.getRoadTransLicensePic());
            byBizId.setRoadTransCertiNumber(command.getRoadTransCertiNumber());
            byBizId.setPeriodEndDate(command.getPeriodEndDate());
            byBizId.setPeriodStartDate(command.getPeriodStartDate());
            byBizId.setPlateNumber(command.getPlateNumber());
            byBizId.setAuthenticationStatus(VehicleInfoEnums.AuthenticationStatusEnum.UNVERIFIED.getCode());
            return qualificationInfoDomainService.updateById(byBizId);
        }

        // 不为空，新增
        Date date = new Date();
        qualificationInfo.setModifyTime(date);
        qualificationInfo.setAuthenticationStatus(VehicleInfoEnums.AuthenticationStatusEnum.UNVERIFIED.getCode());
        qualificationInfo.setSubmitTime(date);
        return qualificationInfoDomainService.insert(qualificationInfo);
    }

    /**
     * @描述 获取基本信息根据手机号模糊查询
     * @参数 [query]
     * @返回值 java.util.List<com.kcwl.carrier.interfaces.dto.BaseInfoDTO>
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public List<BaseInfoDTO> getBaseInfoByMobile(MobileQuery query) {
        return vehicleInfoDomainService.getBaseInfoByMobile(query);
    }

    /**
     * @描述 车和人是否绑定
     * @参数 [query]
     * @返回值 java.lang.Boolean
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public Boolean isExistBind(VehicleIdQuery query) {
        CarrierMappingInfo info = new CarrierMappingInfo();
        info.setCarrierId(query.getUserId());
        info.setVehicleId(query.getVehicleId());
        List<CarrierMappingInfo> infos = carrierMappingDomainService.getMappingList(info);
        if (infos.size() > 0) {
            return Boolean.TRUE;
        } else {
            return Boolean.FALSE;
        }
    }

    /**
     * @描述 校验司机准驾车型跟该车辆是否符合
     * @参数 [query]
     * @返回值 java.lang.Boolean
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public Boolean checkDrivingModel(DrivingModelQuery query) {
        // 查询车辆信息
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(query.getVehicleId());
        // 查询车型信息
        ResponseMessage<VehicleTypeDTO> responseMessage =
            vehicleTypeService.queryVehicleTypeDetail(new VehicleTypeDetailQuery(vehicleInfo.getVehicleType()));
        VehicleTypeDTO vehicleType = responseMessage.getResult();
        if (vehicleType.getAllowedDrivingModels().contains(query.getDrivingModel())) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * @描述 是否存在挂车信息
     * @参数 [query]
     * @返回值 java.lang.Boolean
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public Boolean isExistTrailerInfo(VehicleIdQuery query) {
        // 查询车辆信息
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(query.getVehicleId());

        // 查询车型信息
        ResponseMessage<VehicleTypeDTO> responseMessage =
            vehicleTypeService.queryVehicleTypeDetail(new VehicleTypeDetailQuery(vehicleInfo.getVehicleType()));
        VehicleTypeDTO vehicleTypeDTO = responseMessage.getResult();

        // 查询挂车信息
        VehicleTrailerInfo trailerInfo = vehicleTrailerDomainService.getTrailerDetail(vehicleInfo.getTrailerId());

        // 不是挂车返回true
        if (ObjectUtil.equal(vehicleTypeDTO.getTrailerFlag(), YesNoEnum.NAY.getValue())) {
            return Boolean.TRUE;
        } else {
            // 是挂车没有挂车信息返回false
            if (ObjectUtil.isEmpty(trailerInfo)) {
                return Boolean.FALSE;
            } else {
                // 是挂车，有挂车信息返回true
                return Boolean.TRUE;
            }
        }
    }

    /**
     * @描述 是否是挂车
     * @参数 [query]
     * @返回值 java.lang.Boolean
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public Boolean isTrailer(VehicleIdQuery query) {
        // 查询车辆信息
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(query.getVehicleId());

        // 查询车型信息
        ResponseMessage<VehicleTypeDTO> responseMessage =
            vehicleTypeService.queryVehicleTypeDetail(new VehicleTypeDetailQuery(vehicleInfo.getVehicleType()));
        VehicleTypeDTO vehicleTypeDTO = responseMessage.getResult();

        if (ObjectUtil.equal(vehicleTypeDTO.getTrailerFlag(), YesNoEnum.YEA.getValue())) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * @描述 根据车牌查询车俩列表信息
     * @参数 [query]
     * @返回值 java.util.List<com.kcwl.carrier.interfaces.dto.VehicleInfoDTO>
     * @创建人 zhl
     * @创建时间 2023/1/16
     * @修改人和其它信息
     */
    public List<VehicleInfoDTO> getVehicleList(IdQuery query) {
        // 查询车辆详情
        VehicleInfo vehicleInfo =
            vehicleInfoDomainService.queryByIdOrPlateNumber(query.getId(), query.getPlateNumber());

        // 根据车牌查询车辆列表
        VehicleInfo info = new VehicleInfo();
        info.setPlateNumber(vehicleInfo.getPlateNumber());
        info.setIsDel(YesNoEnum.NAY.getValue());
        List<VehicleInfo> vehicleInfos = vehicleInfoDomainService.queryList(info);
        if (ObjectUtil.isEmpty(vehicleInfos)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.DATA_NOT_EXIST);
        }
        List<VehicleInfoDTO> vehicleInfoDTOS = KcBeanConverter.toList(vehicleInfos, VehicleInfoDTO.class);

        // 根据id集合查询司机列表信息
        List<Long> vehicleIdList = vehicleInfos.stream().map(VehicleInfo::getId).collect(Collectors.toList());
        List<CarrierMappingInfo> carrierMappingInfos = carrierMappingDomainService.getByVehicleIds(vehicleIdList);
        Map<Long, Long> idMap = carrierMappingInfos.stream().collect(Collectors.toMap(CarrierMappingInfo::getCarrierId,
            carrierMappingInfo -> ObjectUtil.isEmpty(carrierMappingInfo.getDriverId()) ? 0
                : carrierMappingInfo.getDriverId()));
        List<Long> driverIdList =
            carrierMappingInfos.stream().map(CarrierMappingInfo::getDriverId).collect(Collectors.toList());
        List<CarrierInfo> carrierInfos = carrierInfoDomainService.getByIds(driverIdList);
        if (!CollectionUtils.isEmpty(carrierInfos) && carrierInfos.size() > 0) {
            Map<Long, CarrierInfo> carrierInfoMap =
                carrierInfos.stream().collect(Collectors.toMap(CarrierInfo::getId, Function.identity()));
            vehicleInfoDTOS.forEach(vehicleInfoDTO -> {
                CarrierInfo carrierInfo = carrierInfoMap.get(idMap.get(vehicleInfoDTO.getCarrierId()));
                if (ObjectUtil.isNotEmpty(carrierInfo)) {
                    vehicleInfoDTO.setDriverId(carrierInfo.getId());
                    vehicleInfoDTO.setDriverName(carrierInfo.getName());
                    vehicleInfoDTO.setDriverMobile(carrierInfo.getMobile());
                }
            });
        }
        return vehicleInfoDTOS;
    }

    /**
     * @描述 审核车辆信息
     * @参数 [command]
     * @返回值 java.lang.Boolean
     * @创建人 zhl
     * @创建时间 2023/1/3
     * @修改人和其它信息
     */
    @KcLock(key = "#command.id", prefix = LockConstants.VEHICLE_AUDIT_KEY)
    public Boolean auditVehicleInfo(AuditVehicleInfoCommand command) {
        // 校验数据
        checkAuditStatus(command);

        if (AuditAuthenticationStatusEnum.SUCCESS.getCode() == command.getAuthenticationStatus()) {
            // 通过
            SpringUtil.getApplicationContext().getBean(VehicleApplicationService.class).approve(command);
        } else if (AuditAuthenticationStatusEnum.FAILURE.getCode() == command.getAuthenticationStatus()) {
            // 驳回
            SpringUtil.getApplicationContext().getBean(VehicleApplicationService.class).reject(command);
        }

        return Boolean.TRUE;
    }

    /**
     * @描述 审核驳回
     * @参数 [command]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2023/1/3
     * @修改人和其它信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void reject(AuditVehicleInfoCommand command) {
        VehicleInfo vehicleInfo = KcBeanConverter.toBean(command, VehicleInfo.class);
        vehicleInfo.setSubmitTime(new Date());
        vehicleInfo.setRejectReason(formattedRejectReason(command.getRejectReason()));
        // app展示
        vehicleInfo.setRejectName(syncAuditRemark(vehicleInfo));
        // crm展示
        vehicleInfo.setAuthenticationRemark(syncAuditRemark(vehicleInfo));
        // 历史备注
        vehicleInfo.setHistoryRemark(syncHistoryRemark(vehicleInfo));
        // 校验驳回原因长度
        checkAuditRejectReasonLength(vehicleInfo.getAuthenticationRemark());

        // 对应挂车也要驳回
        if (ObjectUtil.isNotEmpty(vehicleInfo.getTrailerId())) {
            VehicleTrailerCommand trailerCommand = new VehicleTrailerCommand();
            trailerCommand.setTrailerId(vehicleInfo.getTrailerId());
            trailerApplicationService.rejectVehicleTrailerDetail(trailerCommand);
        }

        // 更新车辆信息
        vehicleInfoDomainService.updateVehicle(vehicleInfo);

        // 添加审核日志
        operateLogApplicationService.rejectVehicleLog(vehicleInfo.getId(),
            Long.parseLong(command.getAuthenticationPerson()), vehicleInfo.getAuthenticationRemark());
    }

    /**
     * @描述 校验驳回原因长度
     * @参数 [remark]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2023/1/3
     * @修改人和其它信息
     */
    private void checkAuditRejectReasonLength(String remark) {
        if (ObjectUtil.isNotEmpty(remark) && remark.length() > VehicleConstant.AUDIT_MAX_LENGTH) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.AUDIT_OVER_LENGTH);
        }
    }

    /**
     * @描述 格式化驳回原因
     * @参数 [rejectReason]
     * @返回值 java.lang.String
     * @创建人 zhl
     * @创建时间 2023/1/3
     * @修改人和其它信息
     */
    public String formattedRejectReason(String rejectReason) {
        if (com.kcwl.framework.utils.StringUtil.isEmpty(rejectReason)) {
            return rejectReason;
        }
        Map map = JSON.parseObject(rejectReason);
        Iterator<Object> iterator = map.keySet().iterator();
        while (iterator.hasNext()) {
            Object key = iterator.next();
            Object objValue = map.get(key);
            if (objValue instanceof JSONArray) {
                JSONArray list = (JSONArray)objValue;
                if (CollectionUtils.isEmpty(list)) {
                    iterator.remove();
                    map.remove(key);
                }
                continue;
            }

            if (com.kcwl.framework.utils.StringUtil.isEmpty(objValue)) {
                iterator.remove();
                map.remove(key);
            }
        }

        return JSONObject.toJSONString(map);
    }

    /**
     * 驳回原因，同步到remark。供app展示
     *
     * @param vehicleInfo 审核条件
     * @return 驳回原因详细说明
     */
    private String syncAuditRemark(VehicleInfo vehicleInfo) {
        Map map = JsonUtil.toMap(vehicleInfo.getRejectReason());
        StringBuilder sb = new StringBuilder();
        map.keySet().forEach(s -> {
            if (VehicleConstant.CUSTOM_REJECT_REASON.equals(s)) {
                sb.append(map.get(s)).append(",");
            } else {
                JsonArray array = JsonUtil.parseJsonArray(map.get(s).toString());
                if (array.size() > 0) {
                    for (JsonElement id : array) {
                        AuditRejectReasonInfo auditRejectReason =
                            auditRejectReasonDomainService.selectId(Long.parseLong(id.getAsString()));
                        if (auditRejectReason != null) {
                            sb.append(auditRejectReason.getDetailReason()).append(",");
                        }
                    }
                }
            }
        });
        if (ObjectUtil.isNotEmpty(vehicleInfo.getAuthenticationRemark())) {
            sb.append(vehicleInfo.getAuthenticationRemark());
            sb.append(",");
        }
        if (sb.length() > 0) {
            return sb.substring(0, sb.toString().length() - 1);
        } else {
            return sb.toString();
        }
    }

    /**
     * 历史备注
     *
     * @param info 审核条件
     * @return 处理后的备注
     */
    private String syncHistoryRemark(VehicleInfo info) {
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(info.getId());
        String authenticationRemark = info.getAuthenticationRemark();
        String historyRemark = vehicleInfo.getHistoryRemark();
        Map<String, String> map = new HashMap<>();
        if (!StringUtil.isEmpty(authenticationRemark)) {
            if (!com.kcwl.framework.utils.StringUtil.isEmpty(historyRemark)) {
                Map historyMap = JsonUtil.fromJson(historyRemark, Map.class);
                String remark = (String)historyMap.get("remark");
                String updateTime = (String)historyMap.get("updateTime");
                map.put("remark", authenticationRemark + "@" + remark);
                map.put("updateTime", DateUtil.getCurDate() + "@" + updateTime);
                //如果超过一千字符长度，就删除历史评论，只记当前评论
                if (JsonUtil.toJson(map).length() > VehicleConstant.HISTORY_MAX_LENGTH) {
                    map.put("remark", authenticationRemark);
                    map.put("updateTime", DateUtil.getCurDate());
                }
            } else {
                map.put("remark", authenticationRemark);
                map.put("updateTime", DateUtil.getCurDate());
            }
            return JsonUtil.toJson(map);
        }
        return historyRemark;
    }

    /**
     * @描述 审核通过
     * @参数 [command]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2023/1/3
     * @修改人和其它信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void approve(AuditVehicleInfoCommand command) {
        // 获取车辆信息
        VehicleInfo vehicleInfo = getModifiedCarrierInfo(command);

        // 校验车牌号
        checkVehiclePlateNumber(vehicleInfo);

        // 查询车型
        VehicleTypeDTO vehicleTypeDTO = null;
        if (ObjectUtil.isNotEmpty(vehicleInfo.getVehicleType())) {
            ResponseMessage<VehicleTypeDTO> vehicleTypeDetail =
                vehicleTypeService.queryVehicleTypeDetail(new VehicleTypeDetailQuery(vehicleInfo.getVehicleType()));
            if (vehicleTypeDetail.isSuccess()) {
                vehicleTypeDTO = vehicleTypeDetail.getResult();
            }
        }

        // 审核挂车信息
        if (ObjectUtil.isNotEmpty(vehicleTypeDTO) && ObjectUtil.equals(vehicleTypeDTO.getTrailerFlag(),
            YesNoEnum.YEA.getValue())) {
            if (ObjectUtil.isEmpty(vehicleInfo.getTrailerId())) {
                VehicleTrailerCommand trailerCommand = new VehicleTrailerCommand();
                trailerCommand.setCarrierId(vehicleInfo.getCarrierId());
                trailerCommand.setVehicleId(vehicleInfo.getId());
                trailerCommand.setPlateColor(command.getTrailerPlateColor());
                trailerCommand.setPlateNumber(command.getTrailerPlateNumber());
                trailerCommand.setTransportationFrontPic(command.getTrailerTransportationFrontPic());
                trailerCommand.setAuthenticationPerson(command.getAuthenticationPerson());
                trailerCommand.setAuthenticationStatus(VehicleInfoEnums.AuthenticationStatusEnum.VERIFIED.getCode());
                trailerApplicationService.addTrailer(trailerCommand);
            } else {
                VehicleTrailerCommand trailerCommand = new VehicleTrailerCommand();
                trailerCommand.setTrailerId(vehicleInfo.getTrailerId());
                trailerCommand.setCarrierId(vehicleInfo.getCarrierId());
                String trailerPlateNumber = command.getTrailerPlateNumber();
                Integer plateColor = command.getTrailerPlateColor();
                String trailerTransportationFrontPic = command.getTrailerTransportationFrontPic();
                if (ObjectUtil.isNotEmpty(trailerPlateNumber) && !trailerPlateNumber.trim().isEmpty()) {
                    trailerCommand.setPlateNumber(trailerPlateNumber);
                }
                if (ObjectUtil.isNotEmpty(plateColor)) {
                    trailerCommand.setPlateColor(plateColor);
                }
                if (ObjectUtil.isNotEmpty(trailerTransportationFrontPic) && !trailerTransportationFrontPic.trim()
                    .isEmpty()) {
                    trailerCommand.setTransportationFrontPic(trailerTransportationFrontPic);
                }
                trailerApplicationService.auditVehicleTrailerDetail(trailerCommand);
            }
        } else if (ObjectUtil.isNotEmpty(vehicleTypeDTO) && !ObjectUtil.equals(vehicleTypeDTO.getTrailerFlag(),
            YesNoEnum.YEA.getValue())) {
            if (ObjectUtil.isNotEmpty(vehicleInfo.getTrailerId())) {
                VehicleTrailerInfo trailerInfo = new VehicleTrailerInfo();
                trailerInfo.setId(vehicleInfo.getTrailerId());
                trailerInfo.setIsDel(YesNoEnum.YEA.getValue());
                vehicleTrailerDomainService.updateById(trailerInfo);
            }
        }

        // 更新车主信息
        CarrierInfo carrierInfo = new CarrierInfo();
        carrierInfo.setIdentityType(command.getIdentityType());
        carrierInfo.setId(command.getCarrierId());
        carrierInfoDomainService.updateCarrierInfoById(carrierInfo);

        // 更新车辆信息
        vehicleInfoDomainService.updateVehicle(vehicleInfo);

        // 更新车辆标签
        bizTagsRefDomainService.saveOrUpdateBizTagsRef(vehicleInfo.getId(), AuditIdentityEnum.VEHICLE.getCode(),
            command.getTagId());

        // 添加审核日志
        operateLogApplicationService.passVehicleLog(vehicleInfo.getId(),
            Long.parseLong(command.getAuthenticationPerson()), vehicleInfo.getAuthenticationRemark());

        // 取消高亮
        fastBindingInfoDomainService.cancelHilight(vehicleInfo.getId());
    }

    private void checkVehiclePlateNumber(VehicleInfo vehicleInfo) {
        // 牵引车重复校验
        // 1.一个司机下，同一车牌号只能存在一个
        // 2.当车牌号已经存在，并且id不是当前车辆id，说明更新车牌号无效
        VehicleInfo info = new VehicleInfo();
        info.setPlateNumber(vehicleInfo.getPlateNumber());
        info.setCarrierId(vehicleInfo.getCarrierId());
        List<VehicleInfo> vehicleListByCarrierIdAndPlateNumber = vehicleInfoDomainService.queryList(info);
        int size = vehicleListByCarrierIdAndPlateNumber.size();
        if (size > 0) {
            if (size > 1) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_REPEATED_ADD);
            }
            VehicleInfo exist = vehicleListByCarrierIdAndPlateNumber.get(0);
            @NotNull Long existId = exist.getId();
            if (existId.longValue() != vehicleInfo.getId().longValue()) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_REPEATED_ADD);
            }
        }
    }

    /**
     * @描述 组装车辆信息
     * @参数 [command]
     * @返回值 com.kcwl.carrier.domain.entity.VehicleInfo
     * @创建人 zhl
     * @创建时间 2023/1/3
     * @修改人和其它信息
     */
    private VehicleInfo getModifiedCarrierInfo(AuditVehicleInfoCommand command) {
        // 查询车辆信息
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(command.getId());

        vehicleInfo.setIsVehicleEnterpriseInformation(command.getIsVehicleEnterpriseInformation());
        vehicleInfo.setDrivingLicensePic(command.getDrivingLicensePic());
        if (ObjectUtil.isNotEmpty(command.getEmissionsStandard()) && !command.getEmissionsStandard()
            .equals(vehicleInfo.getEmissionsStandard())) {
            vehicleInfo.setEmissionsStandard(command.getEmissionsStandard());
        }
        if (!ObjectUtil.equals(command.getPlateNumber(), vehicleInfo.getPlateNumber())) {
            vehicleInfo.setPlateNumber(command.getPlateNumber());
        }

        if (ObjectUtil.isNotEmpty(command.getVehicleType()) && !command.getVehicleType()
            .equals(vehicleInfo.getVehicleType())) {
            vehicleInfo.setVehicleType(command.getVehicleType());
        }

        if (ObjectUtil.isNotEmpty(command.getVehicleCategory()) && !command.getVehicleCategory()
            .equals(vehicleInfo.getVehicleCategory())) {
            vehicleInfo.setVehicleCategory(command.getVehicleCategory());
        }

        if (ObjectUtil.isNotEmpty(command.getAxles()) && !command.getAxles().equals(vehicleInfo.getAxles())) {
            vehicleInfo.setAxles(command.getAxles());
        }

        if (!ObjectUtil.equals(command.getRoadTransCertiNumber(), vehicleInfo.getRoadTransCertiNumber())) {
            vehicleInfo.setRoadTransCertiNumber(command.getRoadTransCertiNumber());
        }

        if (!ObjectUtil.equals(command.getRoadTransLicensePic(), vehicleInfo.getRoadTransLicensePic())) {
            vehicleInfo.setRoadTransLicensePic(command.getRoadTransLicensePic());
        }
        if (!ObjectUtil.equals(command.getRoadTransportPic(), vehicleInfo.getRoadTransportPic())) {
            vehicleInfo.setRoadTransportPic(command.getRoadTransportPic());
        }

        if (ObjectUtil.isNotEmpty(command.getLoads()) && command.getLoads().compareTo(vehicleInfo.getLoads()) != 0) {
            vehicleInfo.setLoads(command.getLoads());
        }

        if (ObjectUtil.isNotEmpty(command.getPlateNumberColor()) && (ObjectUtil.isNotEmpty(
            vehicleInfo.getPlateNumberColor()) || command.getPlateNumberColor()
            .compareTo(vehicleInfo.getPlateNumberColor()) != 0)) {
            vehicleInfo.setPlateNumberColor(command.getPlateNumberColor());
        }

        if (!StringUtils.isEmpty(command.getRelatedPoofPic()) && !ObjectUtil.equals(command.getRelatedPoofPic(),
            vehicleInfo.getRelatedPoofPic())) {
            vehicleInfo.setRelatedPoofPic(command.getRelatedPoofPic());
        }

        if (ObjectUtil.isNotEmpty(command.getIsMaintaining()) && (ObjectUtil.isNotEmpty(
            vehicleInfo.getIsMaintaining()) || command.getIsMaintaining()
            .compareTo(vehicleInfo.getIsMaintaining()) != 0)) {
            vehicleInfo.setIsMaintaining(command.getIsMaintaining());
        }
        if (!SysUtil.isEmpty(command.getDrivingLicenseRegisterTime())) {
            vehicleInfo.setDrivingLicenseRegisterTime(
                DateUtil.getDate(command.getDrivingLicenseRegisterTime(), DateUtil.DEF_DATE_FORMAT));
        }
        if (!SysUtil.isEmpty(command.getDrivingLicenseStartTime())) {
            vehicleInfo.setDrivingLicenseStartTime(
                DateUtil.getDate(command.getDrivingLicenseStartTime(), DateUtil.DEF_DATE_FORMAT));
        }
        if (!SysUtil.isEmpty(command.getDrivingLicenseEndTime())) {
            vehicleInfo.setDrivingLicenseEndTime(
                DateUtil.getDate(command.getDrivingLicenseEndTime(), DateUtil.DATE_TIME));
        }
        if (!SysUtil.isEmpty(command.getDelTime())) {
            vehicleInfo.setDelTime(DateUtil.getDate(command.getDelTime(), DateUtil.MINUTE_FORMAT));
        }
        if (!SysUtil.isEmpty(command.getEtcUpdateTime())) {
            vehicleInfo.setEtcUpdateTime(DateUtil.getDate(command.getEtcUpdateTime(), DateUtil.MINUTE_FORMAT));
        }
        if (!SysUtil.isEmpty(command.getPeriodStartDate())) {
            vehicleInfo.setPeriodStartDate(DateUtil.getDate(command.getPeriodStartDate(), DateUtil.DEF_DATE_FORMAT));
        } else {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.PERIODSTARTDATE_NOT_NULL);
        }

        // 根据道路运输证发证日期计算结束日期
        vehicleInfo.setPeriodEndDate(calPeriodEndDate(vehicleInfo.getPeriodStartDate()));

        // 设置审核信息
        Date date = new Date();//更新提交时间
        vehicleInfo.setSubmitTime(date);
        vehicleInfo.setAuthenticationTime(date);
        vehicleInfo.setId(command.getId());
        vehicleInfo.setCarrierId(command.getCarrierId());
        vehicleInfo.setPlateNumber(command.getPlateNumber());
        vehicleInfo.setAuthenticationStatus(command.getAuthenticationStatus());
        vehicleInfo.setAuthenticationRemark(command.getAuthenticationRemark());
        vehicleInfo.setAuthenticationPerson(command.getAuthenticationPerson());
        vehicleInfo.setHasRelation(command.getHasRelation());
        vehicleInfo.setSize(command.getSize());
        vehicleInfo.setDrivingLicenseNumber(command.getDrivingLicenseNumber());
        vehicleInfo.setSource(command.getVehicleSource());
        vehicleInfo.setLabel(command.getLabel());

        return vehicleInfo;
    }

    /**
     * 计算道路行驶证结束日期
     *
     * @param periodStartDate 道路行驶证发证日期
     * @return 道路行驶证结束日期
     */
    public Date calPeriodEndDate(Date periodStartDate) {
        if (periodStartDate == null) {
            return null;
        }
        // 初始化当前时间
        Calendar curCalendar = Calendar.getInstance();
        curCalendar.set(Calendar.HOUR_OF_DAY, 0);
        curCalendar.set(Calendar.MINUTE, 0);
        curCalendar.set(Calendar.SECOND, 0);
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(periodStartDate);
        startCalendar.set(Calendar.HOUR_OF_DAY, 0);
        startCalendar.set(Calendar.MINUTE, 0);
        startCalendar.set(Calendar.SECOND, 0);

        int curYear = curCalendar.get(Calendar.YEAR);
        int startYear = startCalendar.get(Calendar.YEAR);
        // 发证年度小于当前年度
        if (startYear < curYear) {
            int curMonth = curCalendar.get(Calendar.MONTH);
            int curDay = curCalendar.get(Calendar.DAY_OF_MONTH);
            int startMonth = startCalendar.get(Calendar.MONTH);
            int startDay = startCalendar.get(Calendar.DAY_OF_MONTH);
            // 发证月日大于当前月日，结束日期为当前年度+发证月日
            if (startMonth > curMonth || (startMonth == curMonth && startDay > curDay)) {
                startCalendar.set(Calendar.YEAR, curYear);
                return startCalendar.getTime();
            }
            // 发证月日小于等于当前月日，结束日期为（当前年度 + 1）+当前月日
            else {
                curCalendar.set(Calendar.YEAR, curYear + 1);
                return curCalendar.getTime();
            }
        }
        startCalendar.set(Calendar.YEAR, startYear + 1);
        return startCalendar.getTime();
    }

    /**
     * @描述 检查车辆是否已审核
     * @参数 [command]
     * @返回值 void
     * @创建人 zhl
     * @创建时间 2023/1/3
     * @修改人和其它信息
     */
    private void checkAuditStatus(AuditVehicleInfoCommand command) {
        // 校验承运人信息
        CarrierInfo info = new CarrierInfo();
        info.setId(command.getCarrierId());
        CarrierInfo carrierInfo = carrierInfoDomainService.getCarrierInfo(info);
        if (ObjectUtil.isEmpty(carrierInfo)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.USER_IS_NOT_EXISTS);
        } else {
            if (AuditAuthenticationStatusEnum.SUCCESS.getCode() != carrierInfo.getAuthenticationStatus()) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.CARRIER_AUTH_NOT_APPROVE);
            }
        }

        // 校验车辆信息
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(command.getId());
        if (ObjectUtil.isEmpty(vehicleInfo)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.DATA_NOT_EXIST);
        } else {
            if (ObjectUtil.isNotEmpty(
                vehicleInfo.getAuthenticationStatus()) && AuditAuthenticationStatusEnum.UNAUDITED.getCode() != vehicleInfo.getAuthenticationStatus()) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.AUDITED);
            }
            if (ObjectUtil.isNotEmpty(vehicleInfo.getIsDel()) && Objects.equals(vehicleInfo.getIsDel(),
                YesNoEnum.YEA.getValue())) {
                throw new CarrierUserException(CarrierUseErrorCodeEnum.DELETED);
            }
        }
    }

    /**
     * @描述 批量审核车辆信息
     * @参数 [commandList]
     * @返回值 com.kcwl.carrier.interfaces.dto.VehicleBatchAuditDTO
     * @创建人 zhl
     * @创建时间 2023/1/3
     * @修改人和其它信息
     */
    public VehicleBatchAuditDTO batchAuditVehicleInfo(List<AuditVehicleInfoCommand> commandList) {
        AtomicInteger successCount = new AtomicInteger();
        AtomicInteger rejectCount = new AtomicInteger();
        commandList.forEach(command -> {
            if (ObjectUtil.equals(AuditAuthenticationStatusEnum.SUCCESS.getCode(), command.getAuthenticationStatus())) {
                // 走审核通过逻辑
                SpringUtil.getApplicationContext().getBean(VehicleApplicationService.class).approve(command);
                successCount.getAndIncrement();
            } else {
                // 走审核驳回逻辑
                SpringUtil.getApplicationContext().getBean(VehicleApplicationService.class).reject(command);
                rejectCount.getAndIncrement();
            }
        });
        return new VehicleBatchAuditDTO(successCount.intValue(), rejectCount.intValue(), "");
    }

    /**
     * @描述 撤销驳回车辆
     * @参数 [command]
     * @返回值 java.lang.Boolean
     * @创建人 zhl
     * @创建时间 2023/1/17
     * @修改人和其它信息
     */
    public Boolean cancelRejectVehicleInfo(VehicleCommand command) {
        VehicleInfo vehicleInfo = new VehicleInfo();
        vehicleInfo.setAuthenticationStatus(VehicleInfoEnums.AuthenticationStatusEnum.UNVERIFIED.getCode());
        vehicleInfo.setId(command.getVehicleId());
        vehicleInfo.setAuthenticationRemark("");
        vehicleInfo.setRejectName("");
        vehicleInfo.setRejectReason("");
        vehicleInfoDomainService.updateVehicle(vehicleInfo);

        // 添加审核日志
        operateLogApplicationService.cancelRejectLog(command.getVehicleId(), command.getUserId());

        return Boolean.TRUE;
    }

    public List<OrderVehicleDTO> getAllOrderVehicle(OrderVehicleQuery query) {
        Integer identityType = query.getIdentityType();
        Long driverId = query.getDriverId();
        List<OrderVehicleDTO> vehicleInfos = vehicleInfoDomainService.getAllOrderVehicle(query);
        if (vehicleInfos.isEmpty()) {
            return vehicleInfos;
        }
        //扩展挂车信息
        List<Long> trailerIds =
            vehicleInfos.stream().filter(a -> a.getTrailerId() != null).map(OrderVehicleDTO::getTrailerId)
                .collect(Collectors.toList());
        Map<Long, VehicleTrailerInfo> trailerIdMap = getVehicleTrailerMap(trailerIds);
        //扩展车主信息
        List<Long> carrierIds = vehicleInfos.stream().map(OrderVehicleDTO::getCarrierId).collect(Collectors.toList());
        Map<Long, CarrierInfo> carrierInfoMap = getCarrierInfoMap(carrierIds);
        //扩展车辆类型
        List<Long> vehicleTypes =
            vehicleInfos.stream().map(OrderVehicleDTO::getVehicleType).collect(Collectors.toList());
        Map<Long, VehicleTypeDTO> vehicleTypeMap = getVehicleTypeMap(vehicleTypes);
        vehicleInfos.forEach(vo -> {
            vo.setCarrierName(carrierInfoMap.get(vo.getCarrierId()).getName());
            vo.setCarrierMobile(carrierInfoMap.get(vo.getCarrierId()).getMobile());
            //扩展车主信息
            if (IdentityTypeEnum.CARRIER_SFLTOP.getSubType().equals(identityType)) {
                if (driverId != null && vo.getDriverId() != null && vo.getDriverId() == driverId.longValue()) {
                    vo.setHasRelation(YesNoEnum.YEA.getValue());
                } else {
                    vo.setHasRelation(YesNoEnum.NAY.getValue());
                }
            }
            if (IdentityTypeEnum.CARRIER_DRIVER.getCode().equals(identityType)) {
                //TODO 代收人信息后续再加
                /*CollectorInfoReVo collector = kcwlAccountService.getCollector(vo.getId(), null, userId);
                if (null!=collector){
                    vo.setCollectorName(collector.getCollectorName());
                }*/
            }
            vo.setTrailerAuthStatus(trailerIdMap.get(vo.getTrailerId()) != null ? trailerIdMap.get(vo.getTrailerId())
                .getAuthenticationStatus() : null);
            vo.setTrailerPlateNumber(
                trailerIdMap.get(vo.getTrailerId()) != null ? trailerIdMap.get(vo.getTrailerId()).getPlateNumber()
                    : null);
            if (!vehicleTypeMap.isEmpty()) {
                VehicleTypeDTO vehicleTypeDTO = vehicleTypeMap.get(vo.getVehicleType());
                if (vehicleTypeDTO != null) {
                    vo.setIsTrailer(vehicleTypeDTO.getTrailerFlag());
                    vo.setAllowedDrivingModels(vehicleTypeDTO.getAllowedDrivingModels());
                    vo.setVehicleTypeName(vehicleTypeDTO.getVehicleTypeName());
                }
            }
            //车辆被准驾车型
            if (vo.getAllowedDrivingModels().contains("@")) {
                String[] models = vo.getAllowedDrivingModels().split("@");
                Integer plateNumberColor = vo.getPlateNumberColor();
                if (null != plateNumberColor) {
                    //车牌颜色为黄色或者黄绿色
                    if (plateNumberColor == (VehicleInfoEnums.PlateNumberColorEnum.YELLOW.getCode()) || plateNumberColor == (VehicleInfoEnums.PlateNumberColorEnum.YELLOW_GREEN.getCode())) {
                        vo.setAllowedDrivingModels(models[0]);
                    } else {
                        //车牌颜色是蓝色或者绿色
                        vo.setAllowedDrivingModels(models[1]);
                    }
                }
            }
            //抢单车辆类型匹配处理
            if (com.kcwl.framework.utils.StringUtil.isEmpty(query.getVehicleType()) || query.getVehicleType()
                .equals("-1")) {
                vo.setTypeMatcheStatus(YesNoEnum.NAY.getValue());
            } else {
                if (query.getVehicleType().contains(vo.getVehicleType().toString())) {
                    vo.setTypeMatcheStatus(YesNoEnum.NAY.getValue());
                } else {
                    vo.setTypeMatcheStatus(YesNoEnum.YEA.getValue());
                }
            }

        });
        //        return vehicleInfos.stream().sorted(Comparator.comparing(VehicleInfoDTO::getHasRelation).reversed()).collect(Collectors.toList());
        return vehicleInfos;
    }

    private Map<Long, VehicleTrailerInfo> getVehicleTrailerMap(List<Long> ids) {
        if (ids.isEmpty()) {
            return new HashMap<>();
        }
        List<VehicleTrailerInfo> vehicleTrailers = vehicleTrailerDomainService.getByIds(ids);
        return vehicleTrailers.stream().collect(Collectors.toMap(VehicleTrailerInfo::getId, Function.identity()));
    }

    public Map<Long, CarrierInfo> getCarrierInfoMap(List<Long> ids) {
        if (ids.isEmpty()) {
            return new HashMap<>();
        }
        List<CarrierInfo> carrierInfos = carrierInfoDomainService.getByIds(ids);

        return carrierInfos.stream().collect(Collectors.toMap(CarrierInfo::getId, Function.identity()));
    }

    public Map<Long, VehicleTypeDTO> getVehicleTypeMap(List<Long> ids) {
        if (ids.isEmpty()) {
            return new HashMap<>();
        }
        VehicleTypeQuery condition = new VehicleTypeQuery(ids);
        ResponseMessage<ListResultDTO<VehicleTypeDTO>> responseMessage = vehicleTypeService.queryVehicleType(condition);
        ListResultDTO<VehicleTypeDTO> result = responseMessage.getResult();
        return result.getList().stream().collect(Collectors.toMap(VehicleTypeDTO::getVehicleType, Function.identity()));
    }

    /**
     * 查找车队长分配的车辆
     */
    public VehicleInfoListDTO getCarrierVehicle(CarrierVehicleQuery query) {
        CarrierInfo carrierInfo = carrierInfoDomainService.queryByCarrierId(query.getCarrierId());
        if (carrierInfo == null) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.CARRIER_IS_NOT_EXISTS);
        }
        CarrierMappingQuery carrierMappingQuery = new CarrierMappingQuery();
        carrierMappingQuery.setCarrierId(query.getCarrierId());
        carrierMappingQuery.setDriverId(query.getDriverId());
        carrierMappingQuery.setIsDel(YesNoEnum.NAY.getValue());
        List<CarrierMappingInfo> carrierMappingInfoList =
            carrierMappingDomainService.queryCarrierMappingInfo(carrierMappingQuery);
        if (CollectionUtil.isEmpty(carrierMappingInfoList)) {
            return null;
        }
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(carrierMappingInfoList.get(0).getVehicleId());
        VehicleInfoListDTO result = new VehicleInfoListDTO();
        result.setId(vehicleInfo.getId());
        result.setCarrierId(carrierInfo.getId());
        result.setCarrierName(carrierInfo.getName());
        result.setPlateNumber(vehicleInfo.getPlateNumber());
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean changeTrailer(VehicleTrailerCommand command) {
        // 添加挂车
        trailerApplicationService.addTrailer(command);

        // 删除挂车
        VehicleTrailerInfo trailerInfo = new VehicleTrailerInfo();
        trailerInfo.setIsDel(YesNoEnum.YEA.getValue());
        trailerInfo.setId(command.getTrailerId());
        vehicleTrailerDomainService.updateTrailer(trailerInfo);

        return Boolean.TRUE;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean addCarrierVehicle(CarrierVehicleCommand command) {
        // 认证司机
        carrierUserApplicationService.driverApprove(command.getCarrierApproveCommand());
        // 添加车辆
        VehicleInfoDTO vehicleInfoDTO = addVehicle(command.getVehicleCommand());
        // 添加外协运力
        CarrierForeignDriverCommand carrierForeignDriverCommand =
            setForeignDriverCommand(command.getCarrierApproveCommand().getUserId(), command.getUserId(),
                vehicleInfoDTO.getId());
        foreignDriverApplicationService.addForeignDriver(carrierForeignDriverCommand);
        return Boolean.TRUE;
    }

    private CarrierForeignDriverCommand setForeignDriverCommand(Long driverUserId, Long userId, Long vehicleId) {
        CarrierForeignDriverCommand carrierForeignDriverCommand = new CarrierForeignDriverCommand();
        carrierForeignDriverCommand.setDriverId(driverUserId);
        carrierForeignDriverCommand.setUserId(userId);
        carrierForeignDriverCommand.setVehicleId(vehicleId);
        carrierForeignDriverCommand.setInviteStatus(InviteStatusEnum.AGREED.getCode());
        carrierForeignDriverCommand.setTransportStatus(YesNoEnum.NAY.getValue());
        carrierForeignDriverCommand.setUpdateUserId(userId);
        return carrierForeignDriverCommand;
    }

    public Boolean tmsCancelApprove(IdCommand command) {
        // 校验车辆是否已经认证通过
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(command.getId());
        if (!ObjectUtil.equals(vehicleInfo.getAuthenticationStatus(),
            VehicleInfoEnums.AuthenticationStatusEnum.UNVERIFIED.getCode())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.CANCLE_FAIL);
        }

        // 取消认证
        VehicleInfo info = new VehicleInfo();
        info.setId(vehicleInfo.getId());
        info.setRejectReason("{\"custom\":\"司机取消认证\"}");
        info.setAuthenticationStatus(VehicleInfoEnums.AuthenticationStatusEnum.VERIFIED_FAIL.getCode());
        // 同步历史备注
        vehicleInfo.setHistoryRemark(syncHistoryRemark(vehicleInfo));
        vehicleInfoDomainService.updateVehicle(vehicleInfo);

        return Boolean.TRUE;
    }

    @Transactional(rollbackFor = Exception.class)
    public VehicleInfo carrierTakeVehicle(VehicleRebindCommand command) {
        VehicleInfo vehicleInfo = vehicleInfoDomainService.queryById(command.getHistoryVehicleId());
        // 承运商id
        Long userId = command.getUserId();
        // 校验车辆是否在黑名单中
        if (Objects.equals(isJoinBlackList(vehicleInfo.getPlateNumber()).getFlag(), YesNoEnum.YEA.getValue())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_ILLEGAL_FAIL);
        }
        // 校验车辆是否已添加
        if (checkVehicleExist(vehicleInfo.getPlateNumber(), userId, null)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.REPEATED_APPLY);
        }
        // 校验当前司机绑定车辆总数
        if (checkVehicleCount(userId, carrierInfoDomainService.queryByUserId(userId))) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_NUM_LIMIT);
        }
        // 校验车辆是否已认证
        if (VehicleInfoEnums.AuthenticationStatusEnum.VERIFIED.getCode() == vehicleInfo.getAuthenticationStatus()) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.VEHICLE_AUTH_NOT_APPROVE);
        }
        // 校验车牌号长度、车牌颜色
        VehicleCommand vehicleCommand = KcBeanConverter.toBean(vehicleInfo, VehicleCommand.class);
        this.checkExtParms(vehicleCommand);
        // 校验车辆道路运输证日期
        if (ObjectUtil.isEmpty(vehicleInfo.getPeriodEndDate()) || new Date().after(vehicleInfo.getPeriodEndDate())) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.PERIODENDDATE_NOT_EXIST_OR_OVER);
        }
        // 校验是否是挂车,是否存在挂车信息
        VehicleIdQuery query = new VehicleIdQuery();
        query.setVehicleId(vehicleInfo.getId());
        if (!this.isExistTrailerInfo(query)) {
            throw new CarrierUserException(CarrierUseErrorCodeEnum.TRAILERINFO_NOT_EXIST);
        }
        //承运商添加该车辆
        vehicleInfo.setCarrierId(userId);
        vehicleInfo.setIsDel(YesNoEnum.NAY.getValue());
        vehicleInfo.setDelTime(null);
        vehicleInfo.setSource(YesNoEnum.NAY.getValue());
        // 根据是否是挂车，添加车辆，更新车辆
        if (ObjectUtil.isNotEmpty(vehicleInfo.getTrailerId())) {
            // 查询挂车信息
            VehicleTrailerInfo trailerInfo = vehicleTrailerDomainService.getById(vehicleInfo.getTrailerId());
            // 校验承运商是否已经添加过司机的挂车
            VehicleTrailerCondition vehicleTrailerCondition = new VehicleTrailerCondition();
            vehicleTrailerCondition.setPlateNumber(trailerInfo.getPlateNumber());
            vehicleTrailerCondition.setCarrierId(userId);
            List<VehicleTrailerInfo> list = vehicleTrailerDomainService.getList(vehicleTrailerCondition);
            if (list.isEmpty()) {
                VehicleTrailerPO vehicleTrailerPO = KcBeanConverter.toBean(trailerInfo, VehicleTrailerPO.class);
                vehicleTrailerPO.setCarrierId(userId);
                // 保存挂车信息
                vehicleTrailerDomainService.save(vehicleTrailerPO);
                vehicleInfo.setTrailerId(vehicleTrailerPO.getId());
            }
        }
        // 插入车辆信息
        vehicleInfo.setId(vehicleInfoDomainService.insert(vehicleInfo));
        // 创建承运商司机车辆默认关联关系
        this.addCarrierMapping(vehicleInfo, userId, command.getIdentityType());
        return vehicleInfo;
    }
}
